Java教程:如何使用同步多线程处理业务并让主线程一直等待所有子线程执行完成后再返回

–我们在使用多线程时,经常会new一个内部类或者使用ThreadService,等自定义线程池提供的线程执行方法,但这些均都是异步方法,即主方法一经调用就会立刻返回结束,留下子线程在后台默默运行,在接口返回中无法知道子线程到底执行到哪一步,接下来就给大家讲解一下如何使用同步多线程(CountDownLatch计数器与Callable可回收),让主线程一直等待所有子线程执行完成后再返回,对一些特殊场景非常有帮助,接下来列举具体方法

版本一(CountDownLatch 计数器):

public void synManyThread() {
    List<String> list = Arrays.asList("1", "2", "3");
    // 计数器
    CountDownLatch downLatch = new CountDownLatch(list.size());
    // 创建线程
    ExecutorService executorService = null;
    try {
        executorService = Executors.newCachedThreadPool();
        for (String item : list) {
            // 开启线程
            executorService.execute(() -> {
                try {
                    // 业务处理
                    System.out.println(item);
                } finally {
                    downLatch.countDown();
                }
            });
        }
        downLatch.await();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    } finally {
        if (executorService != null) {
            executorService.shutdown();
        }
    }
}
此方法中CountDownLatch会创建一个初始大小的计数器,每执行完一个子线程数量就会叠加,直到最后计数器满足数量时主线程才会执行到downLatch.await()下一步,但此方法虽简单,也有不足之处,无法接收所有子线程的结果

版本二(Callable可回收):

public void synManyThread() {
	// 创建线程池
	ExecutorService executorService = Executors.newCachedThreadPool();
	List<String> list = Arrays.asList("1", "2", "3");
	try {
		// 创建带有返回值集合
		List<Future<String>> futures = new ArrayList<>();
		list.forEach(item -> {
			// 子线程
			Callable<String> callable = processing(item);
			futures.add(executorService.submit(callable));
		});
		try {
			// 获取所有并发任务的运行结果
			for (Future<String> f : futures) {
				// 从Future对象上获取任务的返回值,并输出到控制台
				log.debug("子线程执行完成,订单号:{}", f.get());
			}
		} catch (Exception e) {
			log.error("子线程执行异常,原因:{}", e.toString());
		}
	} catch (Exception e) {
		log.error("异常:{}", e.toString());
	} finally {
		if (!executorService.isShutdown()) {
			executorService.shutdown();
		}
	}
}

/**
 * 业务处理
 */
private Callable<String> processing(String item) {
	Callable<String> callable = () -> {
		// 业务处理
		return "成功:" + item;
	};
	return callable;
}
此方法将所有子线程的返回结果都接收到futures中,主线程在for循环中接收到所有子线程的返回值后再执行下一步

本次教程到这里就结束了,希望大家多多关注支持(首席摸鱼师 微信同号),持续跟踪最新文章吧~

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要让线执行完成执行主线程,可以使用Java中的CountDownLatch类来实现。CountDownLatch是一个同步工具类,它可以让一个或多个线等待其他线完成操作后执行。 具体实现方式如下: 1. 在主线程中创建一个CountDownLatch对象,设置计数器初始值为1。 2. 在线程中执行完任务后,调用CountDownLatch对象的countDown()方法,计数器减1。 3. 在主线程中调用CountDownLatch对象的await()方法,等待线执行完任务后计数器变为0。 4. 线执行完任务后,计数器减1,主线程调用await()方法等待计数器变为0后继续执行。 示例代码如下: ```java import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(1); ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(() -> { // 线执行任务 System.out.println("线执行任务"); // 计数器减1 countDownLatch.countDown(); }); // 等待计数器变为0 countDownLatch.await(); // 主线程继续执行 System.out.println("主线程继续执行"); // 关闭线程池 executor.shutdown(); } } ``` 在上面的代码中,主线程在创建CountDownLatch对象时将计数器初始值设置为1,然后调用await()方法等待线执行任务后计数器变为0。线执行完任务后调用countDown()方法将计数器减1。主线等待计数器变为0后继续执行。最后记得关闭线程池。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值