【发布时间】:2014-04-30 21:08:27
【问题描述】:
我有一个带有固定线程池的类,我用它来多次运行一个过程。该过程的一部分涉及创建一个 Runnable 并传递给 SwingUtilities.invokeAndWait 以更新我的 Swing GUI。
当我发出再次运行程序的请求时,我希望能够抢占任何正在运行的程序。为此,我保留了上次submit() 调用中的Future,以便我可以cancel() 它。我还保留了最后一个Runnable,所以我可以在它上面设置一个标志,告诉它在run() 时什么都不做,因为它可能已传递给 AWT 事件线程,因此我无法通过取消我的@来停止它987654328@.
但是,无论我做什么,Runnable 都会被执行。这是一个精简的示例:
class Procedure {
private AtomicReference<Updater> updater;
private AtomicReference<Future<?>> currProcedure;
private ExecutorService threadPool;
private Runnable theProcedure;
public Procedure() {
updater = new AtomicReference<Updater>();
currProcedure = new AtomicReference<Future<?>>();
threadPool = Executors.newFixedThreadPool(1);
theProcedure = new Runnable() {
public void run() {
doProcedure();
}
};
}
private void doProcedure() {
// a bunch of stuff
updater.set(new Updater());
try {
SwingUtilities.invokeAndWait(updater.get());
} catch (InvocationTargetException | InterruptedException ex) {
}
// some more stuff
}
public void execute() {
try {
synchronized(this) {
if (null != currProcedure.get()) {
currProcedure.get().cancel(true);
}
if (null != updater.get()) {
updater.get().cancel();
}
}
currProcedure.set(threadPool.submit(theProcedure));
} catch (RejectedExecutionException ex) {
}
}
}
class Updater implements Runnable {
private AtomicBoolean cancelled;
public Updater() {
cancelled = new AtomicBoolean(false);
}
public void cancel() {
cancelled.set(true);
}
public void run() {
if (cancelled.get()) {
return;
}
// do the GUI update
}
}
它会像这样使用:
Procedure p = new Procedure();
p.execute();
p.execute();
实际上,我是从 AWT 事件线程调用Procedure.execute(),所以我认为这可能与它有关;除此之外,我不知道我做错了什么或如何实现我的目标。有什么帮助吗?
编辑:我也尝试将cancel() 我的Updater 退出AWT 事件线程,但无论如何都没有运气:
if (null != currProcedure.get()) {
currProcedure.get().cancel(true);
}
if (null != updater.get()) {
threadPool.submit(new Runnable() {
public void run() {
updater.get().cancel();
}
});
}
编辑 2:我的日志语句似乎暗示我成功中断了updater(我得到了一个java.lang.InterruptedException)但run() 仍然执行(并且cancelled.get() 仍然是@ 987654340@ 在它的末尾)。为什么cancel(true) 不会停止updater 的执行?
【问题讨论】:
-
当您传递到事件队列时,
Runnable将被执行,但我假设您的意思是它没有看到取消状态? -
@MadProgrammer 正是如此。我很难简洁地表达出来。
标签: java multithreading swing future executorservice