调用 SwingWorker 运行 是不是错误以及如何同步 doInBackground?
Is invoking SwingWorker run a mistake and how to synchronize doInBackground?
我使用 SwingWorker 作为一种方法来包装非 swing tasks/actions 之前和之后的方法总是 运行ning 在事件调度线程中(换句话说:我在此之前调用我在 doInBackground 中调用一个抽象方法,然后在 done 方法中调用 after )。这最近开始引起很多麻烦,因为 doInBackground 中发生的任何事情都必须同步。我注意到如果我调用 运行 而不是执行,问题就会消失,但据我了解,运行 方法的工作方式与线程中的相同,它只是在它拥有的完全相同的线程中开始执行被调用而不是创建一个新的,因此如果我从 EDT 调用 运行,doInBackground 将在 EDT 上执行。我的想法正确吗?如何将 doInBackground 方法与调用 worker 上的 execute 的线程同步?
我使用了以下代码,但它似乎正在创建一个线程锁:
private Object LOCK = new Object();
public final void method() {
someObject.before();
SwingWorker<Void, Void> worker1 = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
methodExt();
return null;
}
protected void done() {
someObject.after();
synchronized (LOCK) {
LOCK.notifyAll();
}
}
};
worker1.execute();
synchronized (LOCK) {
try {
LOCK.wait();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
你永远不应该阻止美国东部时间。 SwingWorker
的全部意义在于,它允许您在后台线程上触发任务 运行,并在后台作业完成后在 EDT 运行 上安排其他代码 [=33] =]without 同时阻止 EDT。因此,如果您想在 EDT 上 运行 methodA()
,然后在后台 methodB()
,然后在 B 完成后 methodC()
回到 EDT,答案是调用 methodC()
来自 SwingWorker
.
的 done()
方法
而不是尝试去做
doSomething();
method(); // which blocks waiting for the BG task to complete
doSomethingElse();
您可以将 method()
修改为
public final void method(final Runnable callback) {
someObject.before();
SwingWorker<Void, Void> worker1 = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
methodExt();
return null;
}
protected void done() {
someObject.after();
if(callback != null) callback.run();
}
};
worker1.execute();
}
然后称其为
doSomething();
method(new Runnable() {
public void run() {
doSomethingElse();
}
});
现在 method
returns 立即并且不阻塞 EDT,但是 doSomethingElse
后台任务完成后仍然发生在 EDT
我使用 SwingWorker 作为一种方法来包装非 swing tasks/actions 之前和之后的方法总是 运行ning 在事件调度线程中(换句话说:我在此之前调用我在 doInBackground 中调用一个抽象方法,然后在 done 方法中调用 after )。这最近开始引起很多麻烦,因为 doInBackground 中发生的任何事情都必须同步。我注意到如果我调用 运行 而不是执行,问题就会消失,但据我了解,运行 方法的工作方式与线程中的相同,它只是在它拥有的完全相同的线程中开始执行被调用而不是创建一个新的,因此如果我从 EDT 调用 运行,doInBackground 将在 EDT 上执行。我的想法正确吗?如何将 doInBackground 方法与调用 worker 上的 execute 的线程同步?
我使用了以下代码,但它似乎正在创建一个线程锁:
private Object LOCK = new Object();
public final void method() {
someObject.before();
SwingWorker<Void, Void> worker1 = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
methodExt();
return null;
}
protected void done() {
someObject.after();
synchronized (LOCK) {
LOCK.notifyAll();
}
}
};
worker1.execute();
synchronized (LOCK) {
try {
LOCK.wait();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
你永远不应该阻止美国东部时间。 SwingWorker
的全部意义在于,它允许您在后台线程上触发任务 运行,并在后台作业完成后在 EDT 运行 上安排其他代码 [=33] =]without 同时阻止 EDT。因此,如果您想在 EDT 上 运行 methodA()
,然后在后台 methodB()
,然后在 B 完成后 methodC()
回到 EDT,答案是调用 methodC()
来自 SwingWorker
.
done()
方法
而不是尝试去做
doSomething();
method(); // which blocks waiting for the BG task to complete
doSomethingElse();
您可以将 method()
修改为
public final void method(final Runnable callback) {
someObject.before();
SwingWorker<Void, Void> worker1 = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
methodExt();
return null;
}
protected void done() {
someObject.after();
if(callback != null) callback.run();
}
};
worker1.execute();
}
然后称其为
doSomething();
method(new Runnable() {
public void run() {
doSomethingElse();
}
});
现在 method
returns 立即并且不阻塞 EDT,但是 doSomethingElse
后台任务完成后仍然发生在 EDT