當使用ExecutorService啟動了多個Callable后泳唠,每個Callable會產(chǎn)生一個Future京郑,我們需要將多個Future存入一個線性表,用于之后處理數(shù)據(jù)瀑构。當然裆针,還有更復雜的情況,有5個生產(chǎn)者線程寺晌,每個生產(chǎn)者線程都會創(chuàng)建任務(wù)世吨,所有任務(wù)的Future都存放到同一個線性表中。另有一個消費者線程折剃,從線性表中取出Future進行處理另假。
CompletionService正是為此而存在,它是一個更高級的ExecutorService怕犁,它本身自帶一個線程安全的線性表边篮,無需用戶額外創(chuàng)建。它提供了2種方法從線性表中取出結(jié)果奏甫,poll()是非阻塞的戈轿,若目前無結(jié)果,返回一個null阵子,線程繼續(xù)運行不阻塞思杯。take()是阻塞的,若當前無結(jié)果,則線程阻塞色乾,直到產(chǎn)生一個結(jié)果誊册,被取出返回,線程才繼續(xù)運行暖璧。
public class Test {? ? ??
public static void main(String[] args) throws InterruptedException, ExecutionException {? ? ? ??
? ExecutorService executor = Executors.newCachedThreadPool();? ? ? ?
?? CompletionServicecomp = new ExecutorCompletionService<>(executor);? ? ??
? ? for(int i = 0; i<5; i++) {? ? ? ??
? ? ? comp.submit(new Task());? ? ??
? ? }? ? ? ? ?
?executor.shutdown();? ? ? ??
? int count = 0, index = 1;? ? ? ? ?
?while(count<5) {? ? ? ? ? ? ??
Futuref = comp.poll();
if(f == null) {
? ? ? ? System.out.println(index + " 沒發(fā)現(xiàn)有完成的任務(wù)");
}else {
? ? ? ?System.out.println(index + "產(chǎn)生了一個隨機數(shù): " + f.get());
? ? ? ?count++;
}
index++;
TimeUnit.MILLISECONDS.sleep(500);
}
}
}
class Task implements Callable{
public Integer call() throws Exception {
Random rand = new Random();
TimeUnit.SECONDS.sleep(rand.nextInt(7));
return rand.nextInt();
}
}