CallableインタフェースとRunnableインタフェースの違い

4755 ワード

一、区別の総括:
  • Callable定義の方法はcallであり、Runnable定義の方法はrunである.
  • Callableのcallメソッドには戻り値がありますが、Runnableのrunメソッドには戻り値がありません.これはコアの違いです.
  • Callableのcallメソッドは異常を放出することができ、Runnableのrunメソッドは異常を放出することができない.

  • 二、戻り値の違い
  •   彼らの核心的な違いはCallableがFeatureのオブジェクトを返すことができて、このオブジェクトはスレッドの運行状況を理解することができて、設定はスレッドを閉じることができます!
  • Runbale      
    package com.qunar.synchro;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * Created by qiu.li on 2015/9/21.
     *       Runnable   
     */
    public class TestRunnable implements Runnable {
    
        public static void main(String[] args) {
    
            ExecutorService runnableService = Executors.newFixedThreadPool(3);
    
            Runnable r1 = new TestRunnable();
            runnableService.submit(r1);
            runnableService.submit(new TestRunnable());
            runnableService.submit(new TestRunnable());
            runnableService.submit(new TestRunnable());
            runnableService.shutdown();
            
            System.out.println("go on");
            System.out.println("end");
        }
    
        @Override
        public void run() {
            for(int i=0;i<5; i++) {
                System.out.println(Thread.currentThread().getName() + ";random:" + (int) (Math.random() * 10 * 1000));
                try {
                    Thread.sleep( (int) (Math.random() * 10 * 1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
      
    pool-1-thread-2;random:9491
    go on
    end
    pool-1-thread-3;random:6983
    pool-1-thread-1;random:718
    pool-1-thread-2;random:4214.....
    
    Process finished with exit code 0
      callable   
    package com.qunar.synchro;
    
    import com.sun.org.apache.xalan.internal.utils.FeatureManager;
    
    import java.util.concurrent.*;
    
    /**
     * Created by qiu.li on 2015/9/21.
     */
    public class TestCallable implements Callable {
    
        int i;
    
        public static void main(String[] args) {
    
            ExecutorService runnableService = Executors.newFixedThreadPool(3);
    
            Future r1 =  runnableService.submit(new TestCallable(1));
            Future r2 =  runnableService.submit(new TestCallable(2));
            Future r3 =  runnableService.submit(new TestCallable(3));
            try {
                boolean b2 = r2.get(); //r2  
                boolean b3 = r3.get(); //r3  
                System.out.println(b2);
                System.out.println(b3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            r1.cancel(true);//r1    ,    
            runnableService.shutdownNow();
        }
    
        public TestCallable(int i){
            this.i = i;
        }
    
        @Override
        public Boolean call() {
            try {
                switch (i){
                    case 1:
                        while(true) {
                            System.out.println(Thread.currentThread().getName() + ";i:" + this.i); //     
                            Thread.sleep(200);
                        }
                    default:
                        Thread.sleep(500);
                        System.out.println(Thread.currentThread().getName() + ";i:" + this.i); //    
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return true;
        }
    }
    pool-1-thread-1;i:1
    pool-1-thread-1;i:1
    pool-1-thread-1;i:1
    java.lang.InterruptedException: sleep interrupted
        at java.lang.Thread.sleep(Native Method)
        at com.qunar.synchro.TestCallable.call(TestCallable.java:46)
        at com.qunar.synchro.TestCallable.call(TestCallable.java:10)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    pool-1-thread-2;i:2
    pool-1-thread-3;i:3
    true
    true
    
    Process finished with exit code 0
    
    
    
    
    スレッド1がブロックされている場合(例えばObject.wait,Thread.join,Thread.sleepの3つの方法の1つでブロックされている場合)、CPUを占有していないため、自分の割り込み状態をセットできないため、InterruptedException異常が発生します.
  • の違い:1.CallableはタイプVを返すことができますが、Runnableは2.Callableはchecked exceptionを投げ出すことができませんが、Runnableはできません.3.Runnableはjava 1.1からあり、Callableが1.5になってから加算された4.CallableとRunnableはexecutorsに適用できます.ThreadクラスはRunnableだけをサポートしています.上は簡単な違いですが、実はこの2つのインタフェースは大きな違いがあります.Callableはexecutorsと連携しており,タスクが完了するとすぐに更新されたFutureを得ることができる.RunableはFutureインタフェースを自分で処理し、Callableが実行した状態を取り戻すのが一般的です.主な方法:
  • 1.cancel、Callableの実行をキャンセルし、Callableがまだ完了していない場合
  • .get,Callableの戻り値
  • を得る.
  • 3.isCanceled、
  • がキャンセルされたかどうかを判断
  • 4.isDone、
  • が完了したかどうかを判断する