Future接口是Java标準API的一部分,在java.util.concurrent包中。Future接口是Java線程Future模式的實作,可以來進行異步計算。
有了Future就可以進行三段式的程式設計了,1.啟動多線程任務2.處理其他事3.收集多線程任務結果。進而實作了非阻塞的任務調用。在途中遇到一個問題,那就是雖然能異步擷取結果,但是Future的結果需要通過isdone來判斷是否有結果,或者使用get()函數來阻塞式擷取執行結果。這樣就不能實時跟蹤其他線程的結果狀态了,是以直接使用get還是要慎用,最好配合isdone來使用。
這裡有一種更好的方式來實作對任意一個線程運作完成後的結果都能及時擷取的辦法:使用CompletionService,它内部添加了阻塞隊列,進而擷取future中的值,然後根據傳回值做對應的處理。一般future使用和CompletionService使用的兩個測試案例如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class AsyncThread {
public static void main(String[] args) {
AsyncThread t = new AsyncThread();
List> futureList = new ArrayList>();
t.generate(3,futureList);
t.doOtherThings();
t.getResult(futureList);
}
public void generate(int threadNum,List> fList) {
ExecutorService service = Executors.newFixedThreadPool(threadNum);
for (int i = 0; i < threadNum; i++) {
Future f = service.submit(getJob(i));
fList.add(f);
}
service.shutdown();
}
public void doOtherThings() {
try {
for (int i = 0; i < 3; i++) {
System.out.println("do thing no:" + i);
Thread.sleep(1000 * (new Random().nextInt(10)));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void getResult(List> fList) {
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(getCollectJob(fList));
service.shutdown();
}
public Callable getJob(final int i) {
final int time = new Random().nextInt(10);
return new Callable() {
@Override
public String call() throws Exception {
Thread.sleep(1000 * time);
return "thread-" + i;
}
};
}
public Runnable getCollectJob(final List> fList) {
return new Runnable() {
public void run() {
for (Future future : fList) {
try {
while (true) {
if (future.isDone() && !future.isCancelled()) {
System.out.println("Future:" + future
+ ",Result:" + future.get());
break;
} else {
Thread.sleep(1000);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
}
}
運作結果列印和future放入清單時的順序一緻,為0,1,2:
do thing no:0
do thing no:1
do thing no:2
Future:[email protected],Result:thread-0
Future:[email protected],Result:thread-1
Future:[email protected],Result:thread-2
下面是先執行完的線程先處理的方案:
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
public class testCallable {
public static void main(String[] args) {
try {
completionServiceCount();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public static void completionServiceCount() throws InterruptedException,ExecutionException {
ExecutorService executorService = Executors.newCachedThreadPool();
CompletionService completionService = new ExecutorCompletionService(
executorService);
int threadNum = 5;
for (int i = 0; i < threadNum; i++) {
completionService.submit(getTask(i));
}
int sum = 0;
int temp = 0;
for(int i=0;i
temp = completionService.take().get();
sum += temp;
System.out.print(temp + "\t");
}
System.out.println("CompletionService all is : " + sum);
executorService.shutdown();
}
public static Callable getTask(final int no) {
final Random rand = new Random();
Callable task = new Callable() {
@Override
public Integer call() throws Exception {
int time = rand.nextInt(100)*100;
System.out.println("thead:"+no+" time is:"+time);
Thread.sleep(time);
return no;
}
};
return task;
}
}
運作結果為最先結束的線程結果先被處理:
thead:0 time is:4200
thead:1 time is:6900
thead:2 time is:2900
thead:3 time is:9000
thead:4 time is:7100
0 1 4 3 CompletionService all is : 10
總結
以上就是本文關于Java利用future及時擷取線程運作結果的全部内容,希望對大家有所幫助。感興趣的朋友可以參閱:Java多線程ForkJoinPool執行個體詳解、Java通過賣票了解多線程、Java多線程之readwritelock讀寫分離的實作代碼等,有什麼問題可以随時留言,歡迎大家交流讨論。
相關文章
總結
如果覺得程式設計之家網站内容還不錯,歡迎将程式設計之家網站推薦給程式員好友。
本圖文内容來源于網友網絡收集整理提供,作為學習參考使用,版權屬于原作者。
如您喜歡交流學習經驗,點選連結加入交流1群:1065694478(已滿)交流2群:163560250