java高效获取多线程执行结果
java创建带有返回值的任务。需要实现Callable<T>接口。实现call()方法。如果不希望有返回结果的可以通过实现Runnable接口覆盖run()方法。那如何多线程下高效的获取任务执行的结果呢。
1.下面是常规获取多线程任务返回值结果的方法。
import java.util.ArrayList;
import java.util.List;
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;
public class ExecutorCallableTest {
public static void main(String[] args) {
//创建一个线程池
ExecutorService pools = Executors.newFixedThreadPool(5);
List<Future<Integer>> list = new ArrayList<Future<Integer>>();
//创建多个有返回值的任务
for(int i = 0 ; i <= 10 ; i++){
Future<Integer> futures = pools.submit(new Task(i));
list.add(futures);
}
for(Future<Integer> f : list){
try {
System.out.println(f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
pools.shutdown();
}
}
class Task implements Callable<Integer>{
private Integer taskID;
public Task(Integer taskID) {
this.taskID = taskID;
}
public Integer call() throws Exception {
if(taskID.equals(3))
Thread.sleep(10000);
System.out.println("任务["+taskID+"]开始执行");
return taskID;
}
}
任务[1]开始执行
任务[2]开始执行
任务[0]开始执行
任务[4]开始执行
任务[6]开始执行
任务[9]开始执行
任务[10]开始执行
任务[5]开始执行
0
1
2
任务[8]开始执行
任务[7]开始执行
任务[3]开始执行
3
4
5
6
7
8
9
10
上面的代码中。当我们任务的执行结果时调用Future.get()方法。但是发现get()方法时是阻塞的。当到第三个任务的时候会一直等待任务执行结束获取结果后才能继续向下执行。这样在有些时候是不满足我们的要求的。不能快速的遍历任务执行结果。比如我现在想当有任务执行完我就想获取到,之后进行相应处理。这样就不能满足我们的需求了。
2.通过ExecutorCompletionService实现任务结果的获取
通过ExecutorCompletionService实现任务结果的获取,可以实现将完成的任务先获取。按照这些任务的完成的时间顺序来处理他们的结果。
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;
public class ExecutorCallableTest {
public static void main(String[] args) {
//创建一个线程池
ExecutorService pools = Executors.newFixedThreadPool(5);
CompletionService<Integer> s = new ExecutorCompletionService<Integer>(pools);
//创建多个有返回值的任务
for(int i = 0 ; i <= 10 ; i++){
s.submit(new Task(i));
}
for(int i = 0 ; i <= 10 ; i++){
try {
Future<Integer> f = s.take();
System.out.println(f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
pools.shutdown();
}
}
class Task implements Callable<Integer>{
private Integer taskID;
public Task(Integer taskID) {
this.taskID = taskID;
}
public Integer call() throws Exception {
if(taskID.equals(3))
Thread.sleep(10000);
System.out.println("任务["+taskID+"]开始执行");
return taskID;
}
}
任务[1]开始执行
任务[4]开始执行
任务[5]开始执行
任务[6]开始执行
任务[0]开始执行
任务[2]开始执行
任务[9]开始执行
任务[8]开始执行
任务[7]开始执行
4
1
任务[10]开始执行
5
6
0
2
9
8
7
10
任务[3]开始执行
3