java 多執行緒之future用法和意義
阿新 • • 發佈:2019-01-05
在併發程式設計時,一般使用runnable,然後扔給執行緒池完事,這種情況下不需要執行緒的結果。所以run的返回值是void型別。
如果是一個多執行緒協作程式,比如菲波拉切數列,1,1,2,3,5,8...使用多執行緒來計算。但後者需要前者的結果,就需要用callable介面了。
callable用法和runnable一樣,只不過呼叫的是call方法,該方法有一個泛型返回值型別,你可以任意指定。
執行緒是屬於非同步計算模型,所以你不可能直接從別的執行緒中得到函式返回值。
這時候,Future就出場了。Futrue可以監視目標執行緒呼叫call的情況,當你呼叫Future的get()方法以獲得結果時,當前執行緒就開始 阻塞,直接call方法結束返回結果。
從下面三段程式碼可以看出
runnable介面實現的沒有返回值的併發程式設計。
callable實現的存在返回值的併發程式設計。(call的返回值String受泛型的影響)package test; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class futureTest { public static class Task implements Runnable{ public void run(){ System.out.println("ah"); } } public static void main(String[] args) { //建立執行緒池,無固定長度的執行緒池 ExecutorService es=Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) { es.submit(new Task()); } } }
package test; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import test.futureTest.Task; public class CallableTest { public static class Task implements Callable{ //實現callable介面,是有返回值的call方法,而runnable介面的run方法是沒有返回值 @Override public String call() throws Exception { System.out.println("ah"); return "hello ah!"; } } public static void main(String[] args) { //建立執行緒池,無固定長度的執行緒池 ExecutorService es=Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { es.submit(new Task()); } } }
使用callable介面,使用Future來接收call方法返回的結果,
public static class Task implements Callable<String>{ //實現callable介面,是有返回值的call方法,而runnable介面的run方法是沒有返回值
@Override
public String call() throws Exception {
System.out.println("ah");
return "hello ah!";
}
}
public static void main(String []args) throws InterruptedException, ExecutionException{
List<Future<String>> result = new ArrayList<Future<String>>(); //使用泛型來建立一個list佇列,泛型型別是Future<String>
ExecutorService es=Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
result.add(es.submit(new Task())); //把返回的結果放入list集合中
}
//遍歷list集合,獲取future
for (Future<String> future : result) {
System.out.println(future.get()); //使用future的get方法來獲取call方法返回的結果
}
}
這樣就可以輸出hello ah!