实际开发中很多时候需要同时执行多个任务,等所有任务执行完毕后,拿到所有任务的数据进行处理,如果使用单线程操作,那么总的任务时间就等于所有任务的总和,使用n个线程处理的话那么总处理时间就会约等于任务集合里面最长的一个任务执行时间,可以提高处理速度,使用多线程处理时的麻烦点是如何让主线程等待所有子线程处理完毕(可以使用 线程池的isTerminated()或者用CountDownLatch),利用java8并行流结合forEach 方法可以轻松实现
以下是工具类方法
/**
* 启动多个线程执行n个任务,默认线程数量等于运行计算机上的处理器数量
* @param callables 任务列表
* Djava.util.concurrent.ForkJoinPool.common.parallelism=n;配置ForkJoinPool指定线程数
* System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", n);
* @return 任务的结果集(按照传入顺序)
*/
@SafeVarargs
public static List<Object> executeJobs(Callable<Object>... callables) {
Objects.requireNonNull(callables);
List<Object> futures = new Vector <>();
Stream.of(callables).parallel().forEach(r->{
try {
futures.add(Callable.class.getMethod("call").invoke(r, null));
} catch (Exception e) {
e.printStackTrace();
}
});
return futures;
}
以下是测试代码
@Test
public void test() {
long startTime = System.currentTimeMillis();
List<Object> rest = ThreadTutil.executeJobs(() -> {
sleep(3000);//模拟任务处理时间
System.out.println("执行任务1完成");
return "1";
}, () -> {
sleep(4000);//模拟任务处理时间
System.out.println("执行任务2完成");
return "2";
}, () -> {
sleep(3000);//模拟任务处理时间
System.out.println("执行任务3完成");
return "3";
}, () -> {
sleep(4000);//模拟任务处理时间
System.out.println("执行任务4完成");
return "4";
}, () -> {
sleep(5000);//模拟任务处理时间
System.out.println("执行任务5完成");
return "5";
});
System.out.println("结果:" + rest + " 总耗时:"
+ (System.currentTimeMillis() - startTime));
}
public static void sleep(long millis){
try {
Thread.sleep(millis);
} catch (Exception e) {
e.printStackTrace();
}
}
执行结果: