當向Executor提交批處理任務時,並且希望在它們完成後獲得結果,如果用FutureTask,你可以循環獲取task,並用future.get()去獲取結果,但是如果這個task沒有完成,你就得阻塞在這裏,這個實效性不高,其實在很多場合,其實你拿第一個任務結果時,此時結果並沒有生成並阻塞,其實在阻塞在第一個任務時,第二個task的任務已經早就完成了,顯然這種情況用future task不合適的,效率也不高的,實例如下:
實例一:用一個非complete Service完成的批量任務
package completeservice;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
/**
*
*<p>Test</p>
*<p>Description:</P>
*<p>Company:Cisco CAS</p>
*<p>Department:CAS</p>
*@Author: Tommy Zhou
*@Since: 1.0
*@Version:Date:2011-5-11
*
**/
public class NonCompleteServiceTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<String>[] futures = new FutureTask[10];
/**
* 產生一個隨機數,模擬不同的任務的處理時間不同
*/
for (int i = 0; i < 10; i++) {
futures[i] = executorService.submit(new Callable<String>() {
public String call(){
int rnt = new Random().nextInt(5);
try {
Thread.sleep(rnt*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("run rnt = "+rnt);
return String.valueOf(rnt*1000);
}
});
}
/**
* 獲取結果時,如果任務沒有完成,則阻塞,在順序獲取結果時,
* 可能別的任務已經完成,顯然效率不高
*/
for (int i = 0; i < futures.length; i++) {
System.out.println(futures[i].get());
}
executorService.shutdown();
}
}
package completeservice;
import java.util.Random;
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;
/**
*
*<p>Test</p>
*<p>Description:</P>
*<p>Company:Cisco CAS</p>
*<p>Department:CAS</p>
*@Author: Tommy Zhou
*@Since: 1.0
*@Version:Date:2011-5-11
*
**/
public class CompleteServiceTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
CompletionService<String> completionService = new ExecutorCompletionService<String>(executorService);
/**
* 產生一個隨機數,模擬不同的任務的處理時間不同
*/
for (int i = 0; i < 10; i++) {
completionService.submit(new Callable<String>() {
public String call(){
int rnt = new Random().nextInt(5);
try {
Thread.sleep(rnt*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("run rnt = "+rnt);
return String.valueOf(rnt*1000);
}
});
}
/**
* 獲取結果時,總是先拿到隊列上已經存在的對象,這樣不用依次等待結果
* 顯然效率更高
*/
for (int i = 0; i < 10; i++) {
Future<String> future = completionService.take();
System.out.println(future.get());
}
executorService.shutdown();
}
}