當(dāng)使用ExecutorService啟動(dòng)了多個(gè)Callable后,每個(gè)Callable會(huì)產(chǎn)生一個(gè)Future,我們需要將多個(gè)Future存入一個(gè)線性表,用于之后處理數(shù)據(jù)。當(dāng)然,還有更復(fù)雜的情況,有5個(gè)生產(chǎn)者線程,每個(gè)生產(chǎn)者線程都會(huì)創(chuàng)建任務(wù),所有任務(wù)的Future都存放到同一個(gè)線性表中。另有一個(gè)消費(fèi)者線程,從線性表中取出Future進(jìn)行處理。
CompletionService正是為此而存在,它是一個(gè)更高級(jí)的ExecutorService,它本身自帶一個(gè)線程安全的線性表,無(wú)需用戶(hù)額外創(chuàng)建。它提供了2種方法從線性表中取出結(jié)果,poll()是非阻塞的,若目前無(wú)結(jié)果,返回一個(gè)null,線程繼續(xù)運(yùn)行不阻塞。take()是阻塞的,若當(dāng)前無(wú)結(jié)果,則線程阻塞,直到產(chǎn)生一個(gè)結(jié)果,被取出返回,線程才繼續(xù)運(yùn)行。
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 + " 沒(méi)發(fā)現(xiàn)有完成的任務(wù)");
}else {
? ? ? ?System.out.println(index + "產(chǎn)生了一個(gè)隨機(jī)數(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();
}
}