【发布时间】:2016-03-18 21:56:10
【问题描述】:
我正在编写一个生成分形和分形动画的程序,问题出在动画上...
我有一个生成List<Callable<Long>> tasks 的主线程,其中每个元素都有生成一帧的信息和资源;然后我使用ExecutorService 提交作品。
问题在于如果用户想要停止演算,则无法取消这些辅助线程。代码如下:
public class Animation extends Task<Long> {
protected Long call() throws Exception {
long startTime = System.currentTimeMillis();
WritableImage[] frames = new WritableImage[frameNumber];
List<Callable<Long>> tasks = new ArrayList<>();
updateProgress(count.incrementAndGet(), maxCount);
if (isCancelled()) {
return System.currentTimeMillis() - startTime;;
}
for (int k = 0; k < frameNumber; k++) {
frames[k] = new WritableImage(
(int) start.getCartesianPlane().getWidth(),
(int) start.getCartesianPlane().getHeight());
CartesianFractal tmp = FractalFactory.bulidFractal(
selectedFractal, nextDataBox(k), colorPalette);
tmp.setOnFinish(t -> {
updateProgress(count.incrementAndGet(), maxCount);
return null;
});
tasks.add((Callable<Long>) tmp);
if (isCancelled()) {
return System.currentTimeMillis() - startTime;;
}
}
executor = Executors.newFixedThreadPool(4);
updateProgress(count.incrementAndGet(), maxCount);
if (isCancelled()) {
return System.currentTimeMillis() - startTime;
}
try {
result = executor.invokeAll(tasks);
}
catch (InterruptedException ex) {
System.err.println(ex.toString());
}
// Check if all tasks are finished
boolean finished = false;
while (!finished) {
finished = true;
// Check if it is all done
for (Future<Long> r : result) {
finished = finished && r.isDone(); // THE PROGRAM BLOCKS HERE
// Check if the task was cancelled
if (isCancelled()) {
// Cancell all task
tasks.stream().forEach((t) -> {
((CartesianFractal)t).myCancel();
});
// Turnoff the executor
executor.shutdown();
return System.currentTimeMillis() - startTime;
}
}
}
// Turnoff the executor
executor.shutdown();
updateProgress(count.incrementAndGet(), maxCount);
makeAnimation();
updateProgress(count.incrementAndGet(), maxCount);
return System.currentTimeMillis() - startTime;
}
}
我真的不明白为什么Future.isDone()像Future.get()这样屏蔽程序!
这是我的第一个问题,所以我希望一切都好。
【问题讨论】:
-
它是否真的 阻塞在那里(因为线程处于
BLOCKED状态),或者它似乎只是因为忙于等待而停止在那条线上? -
顺便说一下,
CompletionService可能更容易在线程完成时收到通知。 -
另一个顺便说一句:您可以将大部分逻辑拆分为
void callInternal(),而不是让return System.currentTimeMillis() - startTime;分散在您的代码中,而void callInternal()是从call() { long startTime = ...; callInternal(); return System.currentTimeMillis() - startTime; }调用的。另外,考虑将executor.shutDown()放入单个finally块中。 -
(...或编写一个通用的
TimedCallable类,它包含对委托Callable的调用(或Runnable,我想),因此您可以在其他地方重用计时逻辑) .
标签: java multithreading javafx-8 java.util.concurrent