CallableインタフェースとRunnableインタフェースの違い
4755 ワード
一、区別の総括: Callable定義の方法はcallであり、Runnable定義の方法はrunである. Callableのcallメソッドには戻り値がありますが、Runnableのrunメソッドには戻り値がありません.これはコアの違いです. Callableのcallメソッドは異常を放出することができ、Runnableのrunメソッドは異常を放出することができない.
二、戻り値の違い 彼らの核心的な違いはCallableがFeatureのオブジェクトを返すことができて、このオブジェクトはスレッドの運行状況を理解することができて、設定はスレッドを閉じることができます! の違い: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、 が完了したかどうかを判断する
二、戻り値の違い
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異常が発生します.