在当今这个信息爆炸的时代,多线程编程已成为高效处理并发任务的重要工具。然而,如何在多线程编程中优雅地等待线程结果并继续后续操作,却是一个让人头疼的问题。今天,我们就来探讨如何使用Executors.newFixedThreadPool和executorService.submit(callable)来解决这个问题,让你的代码更加高效、易读。
一、为什么要使用多线程等待线程结果?
在Java中,多线程编程可以显著提高程序的执行效率,尤其是在处理大量并发任务时。然而,当多个线程同时执行时,如何确保它们按照预期的顺序执行,即等待某个线程完成后才继续执行后续操作,就显得尤为重要。这不仅可以避免线程间的竞争和冲突,还能保证程序的正确性和稳定性。
二、Executors.newFixedThreadPool的优势
Executors.newFixedThreadPool是Java中提供的一个非常实用的线程池创建方法。它创建了一个固定大小的线程池,可以重复利用已创建的线程执行新任务,避免了频繁创建和销毁线程带来的性能损耗。此外,线程池还可以有效地控制并发线程的数量,防止因过多线程同时执行而导致的系统资源耗尽。
三、executorService.submit(callable)的使用方法
executorService.submit(callable)是线程池ExecutorService中的一个重要方法。它允许你将一个Callable任务提交给线程池执行,并返回一个Future对象,该对象代表了任务的执行结果。通过Future对象,你可以获取任务的执行结果,或者在任务完成时执行回调函数等操作。
/**
* 加入线程
* @param callable
*/
public void submit(Callable<Object> callable){
Future<Object> future = executorService.submit(callable);
futures.add(future);
}
四、如何优雅地等待线程结果并继续后续操作
在使用executorService.submit(callable)提交任务后,你可以通过调用Future.get()方法来获取任务的执行结果。这个方法会阻塞当前线程,直到任务完成并返回结果。虽然这种方法可以获取到结果,但它并不优雅,因为它会阻塞当前线程,影响程序的并发性能。
为了优雅地等待线程结果并继续后续操作,我们可以通过Future.get()方法获取结果;如果任务还未完成,我们可以选择执行其他操作,或者通过轮询的方式等待任务完成。
/**
* 加入线程
* @param callable
*/
public void submit(Callable<Object> callable){
Future<Object> future = executorService.submit(callable);
futures.add(future);
}
/**
* 等待线程全部执行完毕,并返回结果数据
*/
public List<Object> waitComplete(){
try {
// 等待所有任务完成并打印结果
for (Future<Object> future : futures) {
result.add(future.get());// future.get()会阻塞,直到结果可用
}
return this.result;
}catch (Exception exception){
throw new GlobalException("获取线程结果失败:" + exception.getMessage());
}finally {
executorService.shutdown();
}
}
此外,我们还可以通过CompletableFuture类来实现更加灵活的异步编程。CompletableFuture提供了丰富的API,支持任务的链式调用、异常处理、结果转换等操作,使得多线程编程变得更加简单和高效。
五、总结
通过Executors.newFixedThreadPool和executorService.submit(callable)的结合使用,我们可以轻松地实现多线程编程,并通过优雅地等待线程结果来继续后续操作。这不仅提高了程序的执行效率,还增强了程序的可读性和可维护性。在未来的开发中,我们应该充分利用这些多线程编程技巧,编写出更加高效、稳定的代码。
完整代码
public class FixedThreadPoolUtil {
int nThreads;
ExecutorService executorService = null;
List<Future<Object>> futures = new ArrayList<>();
List<Object> result = new ArrayList<>();
/**
* 新建线程池,指定线程池大小
* @param nThreads
*/
public FixedThreadPoolUtil(int nThreads){
this.nThreads = nThreads;
executorService = Executors.newFixedThreadPool(nThreads);
}
/**
* 加入线程
* @param callable
*/
public void submit(Callable<Object> callable){
Future<Object> future = executorService.submit(callable);
futures.add(future);
}
/**
* 等待线程全部执行完毕,并返回结果数据
*/
public List<Object> waitComplete(){
try {
// 等待所有任务完成并打印结果
for (Future<Object> future : futures) {
result.add(future.get());// future.get()会阻塞,直到结果可用
}
return this.result;
}catch (Exception exception){
throw new GlobalException("获取线程结果失败:" + exception.getMessage());
}finally {
executorService.shutdown();
}
}
/**
* 关闭线程池
*/
protected void finalize() {
if (executorService != null) {
executorService.shutdown();
}
}
/**
* 调用demo
*/
private void demo(){
FixedThreadPoolUtil fixedThreadPoolUtil = new FixedThreadPoolUtil(2);
Callable<Object> callable1 = new Callable<Object>() {
private int tenxunService;
private String imgUrl;
public Callable<Object> withParameter(int tenxunService,String imgUrl) {
this.tenxunService = tenxunService;
this.imgUrl = imgUrl;
return this;
}
@Override
public Object call(){
return this.imgUrl;
}
}.withParameter(1,"1");
fixedThreadPoolUtil.submit(callable1);
List<Object> objects = fixedThreadPoolUtil.waitComplete();
System.out.println(objects);
}
}