每天一例多執行緒[day19]-----JDK實現Future的用法
-
import java.util.concurrent.Callable;
-
import java.util.concurrent.ExecutorService;
-
import java.util.concurrent.Executors;
-
import java.util.concurrent.Future;
-
import java.util.concurrent.FutureTask;
-
public class UseFuture implements Callable<String>{
-
private String para;
-
public UseFuture(String para){
-
this.para = para;
-
}
-
/**
-
* 這裡是真實的業務邏輯,其執行可能很慢
-
*/
-
@Override
-
public String call() throws Exception {
-
//模擬執行耗時
-
Thread.sleep(5000);
-
String result = this.para + "處理完成";
-
return result;
-
}
-
//主控制函式
-
public static void main(String[] args) throws Exception {
-
String queryStr = "query";
-
//構造FutureTask,並且傳入需要真正進行業務邏輯處理的類,該類一定是實現了Callable介面的類
-
FutureTask<String> future = new FutureTask<String>(new UseFuture(queryStr));
-
FutureTask<String> future2 = new FutureTask<String>(new UseFuture(queryStr));
-
//建立一個固定執行緒的執行緒池且執行緒數為1,
-
ExecutorService executor = Executors.newFixedThreadPool(2);
-
//這裡提交任務future,則開啟執行緒執行RealData的call()方法執行
-
/**
-
* 執行緒池中的submit和execute方法的區別:
-
* 第一點是submit可以傳入實現Callable介面的例項物件
-
* 第二點是submit方法有返回值
-
*/
-
// f1.get() 如果執行完畢則返回null
-
Future f1 = executor.submit(future);
-
Future f2 = executor.submit(future2);
-
System.out.println("請求完畢");
-
try {
-
//這裡可以做額外的資料操作,也就是主程式執行其他業務邏輯
-
System.out.println("處理實際的業務邏輯...");
-
Thread.sleep(1000);
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
/**
-
* future.get方法非同步等待獲取執行緒池的處理的最終結果
-
* 如果call()方法沒有執行完成,則依然會進行等待
-
*
-
*/
-
System.out.println("資料:" + future.get());
-
System.out.println("資料:" + future2.get());
-
executor.shutdown();
-
}
-
}
列印:
-
請求完畢
-
處理實際的業務邏輯...
-
資料:query處理完成
-
資料:query處理完成
分析:我們在主函式中定義兩個FutureTask,並分別傳入實現了Callable介面的物件,定義一個固定數量執行緒池,將FutureTask物件submit進執行緒池,每個JDK實現的執行緒池都有execute和submit兩個方法,這兩個方法的區別:
1 submit可以傳入實現Callable介面的例項物件
2 submit方法有Future型別返回值(這個返回的Future物件有個get方法,可以返回執行緒池中提交的對應任務是否執行完畢,是則返回null)
我們可以通過定義的FutureTask例項物件的get方法去非同步獲取執行緒池中Callable物件的處理結果,如果call()沒有執行完畢,則會繼續等待。