在我们日常使用线程池的时候,经常会有需要获得线程处理结果的时候。此时我们通常有两种做法。
1. 使用并发容器将callable.call() 的返回Future存储起来。然后使用一个消费者线程去遍历这个并发容器,调用Future.isDone()去判断各个任务是否处理完毕。然后再处理响应的业务。
import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; public class ExecutorResultManager { public static void main(String[] args) { // 队列 BlockingQueue<Future<String>> futures = new LinkedBlockingQueue<>(); // 生产者 new Thread() { @Override public void run() { ExecutorService pool = Executors.newCachedThreadPool(); for (int i=0; i< 10; i++) { int index = i; Future<String> submit = pool.submit(new Callable<String>() { @Override public String call() throws Exception { return "task done" + index; } }); try { futures.put(submit); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); // 消费者 new Thread() { @Override public void run() { while(true) { for (Future<String> future : futures) { if(future.isDone()) { // 处理业务 // ............. }; } } } }.start(); } }
2. 使用jdk 自带线程池结果管理器:ExecutorCompletionService。它将BlockingQueue 和Executor 封装起来。然后使用ExecutorCompletionService.submit()方法提交任务。
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ExecutorCompletionServiceManager {
public static void main(String[] args) {
ExecutorCompletionService<String> service = new ExecutorCompletionService<String>(
Executors.newCachedThreadPool());
// 生产者
new Thread() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
int index = i;
service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "task done" + index;
}
});
}
}
}.start();
// 消费者
new Thread() {
@Override
public void run() {
try {
Future<String> take = service.take();
// do some thing........
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
另外一个例子:
public class Application {
public static void main(String[] args) throws Exception {
//SpringApplication.run(Application.class, args);
Application application = new Application();
for(int i=0; i<10000; i++){
Application.Sub sub = application.new Sub();
boolean value = sub.test();
System.out.println("end="+value);
}
}
class Sub{
public Boolean test() throws Exception{
ExecutorService service = Executors.newFixedThreadPool(2);
CompletionService<Boolean> completionService = new ExecutorCompletionService<Boolean>(service);
try {
for(int i=0; i<1; i++){
completionService.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Thread.sleep(100);
//throw new NullPointerException("lalalalala");
return true;
}
});
}
for(int i=0; i<1; i++){
System.out.println(completionService.take().get());
}
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
} finally {
service.shutdown();
}
return true;
}
}
}