2

2 つのスレッドがあります。TaskThread、BackgroundThread。

TaskThread は、「データ受信」セマフォでブロックします。

synchronized (receiveSemaphore) {
    while (!dataIsReady) {
        try {
            receiveSemaphore.wait();
        } catch (InterruptedException e) {
        }
    }
    ...
}

BackgroundThread は、「データ受信」セマフォで待機しているすべてのスレッドに通知します

receiveSemaphore.notifyAll();

残念なことに、物事がうまくいかないことがあり、BackgroundThread は待機中のスレッドに通知するステートメントを実行しません。ユーザーが待ちきれなくなったとき、どのようにキャンセルしますか?

JavaFX2 UI に [キャンセル] ボタンがあります。JavaFX2 では、示された唯一の例は、ループで実行され、isCancelled() フラグをチェックするスレッドを持っています。

http://docs.oracle.com/javafx/2/api/javafx/concurrent/Task.html

繰り返しますが、タスク スレッド自体がブロックされている場合、どうすればそこからキャンセルできますか?

4

1 に答える 1

1

キャンセル ボタンが押されたら、タスクのキャンセルを呼び出します。これにより、待機中のタスクが中断され、実行が InterruptedException ブロックに流れます。ここで、割り込みの原因がキャンセル呼び出しであるかどうかを確認し、そうであれば、Task の call メソッドから戻り、効果的にタスクをキャンセルして終了します。 .

あなたのサンプルは、実際にはTask ドキュメントの「A Simple Loop With Progress Notification And Blocking Calls」というタイトルのサンプルとかなり似ていますが、ループが含まれていないため、サンプルはさらに単純であり、ブロッキング呼び出しについてのみ心配する必要があります。

バックグラウンドで、タスクでキャンセルを呼び出すと、スレッドに割り込みが送信され、Taskスレッドで が生成さInterruptedExceptionれます。

ここにいくつかのサンプルコードがあります。

// Task cancel button logic.
cancelButton.setOnAction(new EventHandler<ActionEvent>() {
    @Override public void handle(ActionEvent t) {
        task.cancel();
    }
})
....
// Task call method logic
synchronized (receiveSemaphore) {
    while (!dataIsReady) {
        try {
            receiveSemaphore.wait();
        } catch (InterruptedException e) {
            if (isCancelled()) {
                return;
            }
        }
    }
    ...
}
于 2013-03-19T23:23:16.037 に答える