8

タイムアウトをExecutorService処理するスレッドを1つだけ作成したのに、次のコードが正しく「10 15」を出力するのはなぜですか?シングルスレッドエグゼキュータで以前のタスクをキャンセルせずに、スケジュールを何度も呼び出すことができるのはなぜですか?

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class TestExecutorService implements Runnable {
    public static ScheduledExecutorService SERVICE = Executors.newSingleThreadScheduledExecutor();
    private int delay;


    public TestExecutorService(int delay) {
        this.delay = delay;
    }

    public void run () {
        System.out.println(delay);
    }

    public static void main (String[] args) {
        SERVICE.schedule(new TestExecutorService(10), 10, TimeUnit.SECONDS);
        SERVICE.schedule(new TestExecutorService(15), 15, TimeUnit.SECONDS);

        SERVICE.shutdown();
    }
}
4

2 に答える 2

13

Javadocから:

タスクは順番に実行されることが保証されており、常にアクティブになるタスクは1つだけです。

「処理タイムアウト」と「タスク実行」の違いが答えの鍵です。「シングルスレッド」は「一度に1つのタイムアウトのみを処理する」ことを意味すると想定しますが、実際には「一度に1つのタスクのみを実行する」ことを意味します。すべてのタイムアウトは同時に処理されますが、タスクの実行が停止する前に一方のタイムアウトに達した場合、実行する前にもう一方のタイムアウトが終了するのを待つ必要があります。

于 2012-12-18T07:03:46.333 に答える
10

この場合、 Javadocを読むと非常に役立ちます。エグゼキュータは単一のスレッドで作成されますが、無制限のキューで動作することを説明しています。これは、複数のタスクをエグゼキュータに送信でき、キューの最大境界(この場合は無限大)まで、またはJVMのリソースがなくなるまで、次々に実行するためにキューに入れられることを意味します。

無制限のキューで動作する単一のワーカースレッドを使用するエグゼキュータを作成します。(ただし、シャットダウン前の実行中に障害が発生したためにこの単一スレッドが終了した場合、後続のタスクを実行する必要がある場合は、新しいスレッドが代わりに使用されます。)タスクは順次実行されることが保証され、アクティブになるタスクは1つだけです。いつでも。他の点では同等のnewFixedThreadPool(1)とは異なり、返されたエグゼキュータは、追加のスレッドを使用するように再構成できないことが保証されています。

この例では、2つのタスクがキューに入れられ、次々に実行されます。これが、(期待される)出力を取得する理由です。

于 2012-12-18T06:59:08.600 に答える