Callable(簡單) callable介面和runnable介面類似,都是為了執行另外一條線程而設計的,區別是Runnable不會返回結果也不會拋出異常。 1、可以有返回值 2、可以拋出異常 3、方法不同;run()/call(); Runnable 實現Runnable介面,重寫run方法,無 ...
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的返回值可能會產生對該方法調用實例的線程阻塞