私は各要素が一つのフレームを生成するための情報やリソースを持っているList<Callable<Long>> tasks
を生成し、メインスレッドを持っている...問題はアニメーションであり、フラクタルフラクタルアニメーションを生成するためのなぜfuture isDone()がFuture get()のようなプログラムをブロックするのか?
を、プログラムを書いています。私は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()
のようなプログラムをブロックし、なぜ私は本当に理解していません!
これは私の最初の質問です。だから、これは大丈夫です。
はそれをしない:
プログラム
は忙しいように見えるので、私はこの解決策を見つけた:Animation
クラスになるものの:私はこのコードを使用するためのすべてのジョブをキャンセル本当に*ブロックしています(スレッドが 'BLOCKED'状態になっています)か、ビジー状態であるためその行で停止しているようですか? –
ちなみに、CompletionServiceは、スレッドが完了したときに通知される簡単な方法です。 –
もう1つのBTW:あなたのコードに散らばっている 'System.currentTimeMillis() - startTime;を返すのではなく、' call(){long startTime = ...; callInternal();戻り値System.currentTimeMillis() - startTime; } '。また、 'executor.shutDown()'を単一の 'finally'ブロックに入れることを検討してください。 –