Callable、FutureTask、Futureの詳細はjavaの同時プログラミングを理解します


一.CallableインタフェースとRunnableインタフェースの違い
Javaスレッドを作成するには、2つの方法がよく使用されます.
  • 1は直接Thread
  • を継承する.
  • もう1つはRunnableインタフェース
  • を実装することである.
    しかし、この2つの方法には、タスクを実行した後、実行結果を直接取得できないという欠陥があります.
    1.インタフェース定義
    1.1ケーブルコネクタ
    public interface Callable {
        V call() throws Exception;
    }

    1.2 Runnableインタフェース
    public interface Runnable {
        public abstract void run();
    }

    2.区別
  • Runnableには戻り値がありません.Callableは実行結果(汎用)を返すことができます.
  • Runnable異常は内部でしか処理できず、上へ投げ続けることはできない.Callableインタフェースのcall()メソッドでは、例外を放出できます.
  • CallableはFutureTaskまたはFutureに合わせて使用する必要があります.

  • 二.FutureインタフェースとFutureTask実装クラス
    1.Futureインタフェースは5つの方法を定義している
    public interface Future {
        boolean cancel(boolean mayInterruptIfRunning);
        boolean isCancelled();
        boolean isDone();
        V get() throws InterruptedException, ExecutionException;
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }
    
  • cancelメソッドは、タスクをキャンセルするために使用され、タスクのキャンセルに成功した場合はtrueを返し、タスクのキャンセルに失敗した場合はfalseを返します.パラメータmayInterruptIfRunningは、実行中のタスクをキャンセルしても完了していないタスクを許可するかどうかを示し、trueを設定すると、実行中のタスクをキャンセルできることを示します.タスクが完了した場合、mayInterruptIfRunningがtrueであろうとfalseであろうと、このメソッドはfalseを返します.すなわち、完了したタスクをキャンセルするとfalseを返します.タスクが実行中の場合、mayInterruptIfRunningがtrueに設定されている場合はtrueを返し、mayInterruptIfRunningがfalseに設定されている場合はfalseを返します.タスクがまだ実行されていない場合は、mayInterruptIfRunningがtrueであれfalseであれ、trueが返されます.
  • isCancelledメソッドは、タスクがキャンセルに成功したかどうかを示し、タスクが正常に完了する前にキャンセルに成功した場合はtrueを返します.
  • isDoneメソッドは、タスクが完了したかどうかを示し、タスクが完了した場合、trueを返します.
  • get()メソッドは実行結果を取得するために使用され、このメソッドはブロックを生成し、タスクの実行が完了するまで戻ってくる.
  • get(long timeout,TimeUnit unit)は、実行結果を取得するために使用され、指定された時間内に結果が取得されていない場合はnullに直接戻ります.

  • 2.FutureTaskはRunnableFutureインタフェースを実現し、RunnableFutureはRunnableインタフェースとFutureインタフェースを継承した
    public class FutureTask implements RunnableFuture
    public interface RunnableFuture extends Runnable, Future {
        void run();
    }

    三.基本的な使い方の例
    1. Runnable
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("     ...");
        }
    };
    Thread thread = new Thread(runnable);
    thread.start();

    2. Callable
    2.1 FutureTask
    Callable < Integer > callable = new Callable < Integer > () {
        @Override
        public Integer call() throws Exception {
            System.out.println("     ...");
            return 100;
        }
    };
    FutureTask < Integer > futureTask = new FutureTask < Integer > (callable);
    new Thread(futureTask).start();
    //   1 ,     
    TimeUnit.SECONDS.sleep(1);
    if(futureTask.isDone()) {
        System.out.println("      :" + futureTask.get());
    }

    2.2 Future
    Callable < Integer > callable = new Callable < Integer > () {
        @Override
        public Integer call() throws Exception {
            System.out.println("     ...");
            return 100;
        }
    };
    ExecutorService service = Executors.newCachedThreadPool();
    Future < Integer > future = service.submit(callable);
    //   1 ,     
    TimeUnit.SECONDS.sleep(1);
    if(futureTask.isDone()) {
        System.out.println("      :" + future.get());
    }