Callable(簡單)
callable介面和runnable介面類似,都是為了執行另外一條執行緒而設計的,區別是Runnable不會返回結果也不會丟擲異常。
1、可以有返回值
2、可以丟擲異常
3、方法不同;run()/call();
Runnable
實現Runnable介面,重寫run方法,無返回值
//原執行緒
class RunnableThread implements Runnable{
@Override
public void run() {
}
}
Callable
實現Callable介面,重寫call方法,有返回值,可在實現介面時設定
//callable執行緒
class CallableThread implements Callable<String>{
@Override
public String call() throws Exception {
return null;
}
}
Callable中泛型的引數等於方法的返回型別
啟動callable
Thread類中沒有填入callable介面的過載方法,所以我們需要透過適配類完成操作
透過查詢Runnable介面的實現類,能夠發現有一個FutureTask中提供了Callable引數的構造方法
所以,可以透過FutureTask來作為一箇中間人的角色使用執行緒執行callable的實現類。
具體程式碼
package org.example.callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableTest {
public static void main(String[] args) {
// new Thread(()->{new Runnable()}).start();
// new Thread(()->{new FutureTask<V>()}).start();
// new Thread(()->{new FutureTask<V>( Callable )}).start();
CallableThread thread = new CallableThread();//怎樣啟動Callable
FutureTask task = new FutureTask(thread);//適配類
new Thread(task,"A").start();//正常列印兩個call,但是這邊只會列印一個,結果會被快取,提高效率
new Thread(task,"B").start();
try {
String o = (String) task.get();//get方法可能產生阻塞,耗時操作時;透過非同步操作或者將它放在最後使用
System.out.println(o);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
}
//callable執行緒
class CallableThread implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("call");
return "cals";
}
}
細節
1、為了提高效率所以有快取
2、耗時操作時,獲取callable的返回值可能會產生對該方法呼叫例項的執行緒阻塞