thread的join方法

文章讲述了在单元测试中遇到Redis连接失败的问题,通过调整线程执行顺序、使用join方法、线程池和CountDownLatch/CompletableFuture等工具进行线程同步,确保资源有效利用并避免频繁创建和关闭线程造成的资源消耗。
摘要由CSDN通过智能技术生成

测试redis的某些方法时,在单元测试中,发现redis连接资源失败。

加sleep睡眠之后就没有问题。或者是在start之后在join一下也没有问题。

经过测试之后发现是因为主线程执行时间过短,redis连接已经被释放了,所以子线程获取不到。

thread.join()方法官方解释是等待线程终止。

也就是说调用join方法的线程优先执行,其他正在执行的线程阻塞,等待该线程执行完毕后再执行。

@Test
    public void mainTest() throws InterruptedException {
        Thread thread444 = new Thread(() -> test444());
        Thread thread555 = new Thread(() -> test555());
        thread444.start();
        thread555.start();
        thread444.join();
        thread555.join();
    }

上述方法则是444和555同时执行(可能444先执行完也可能555先执行完),并且两个线程任务都执行完成之后,mainTest线程再完成;

@Test
    public void mainTest() throws InterruptedException {
        Thread thread444 = new Thread(() -> test444());
        Thread thread555 = new Thread(() -> test555());
        thread444.start();
        thread444.join();
        
        thread555.start();
        thread555.join();
    }

上述方法则是444先执行完,再执行555,最后mainTest线程执行完毕。

如果说每开一个线程,都立马join的话,就和没有单开线程的效果一样了,反而因为线程的频繁创建与关闭消耗服务器资源。

如果使用线程池的话,也会有类似的方法来实现join的效果

当前项目正式环境使用的是executor.awaitTermination()方法

//多线程异步执行
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("pushOriginOrder-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
ThreadPoolExecutor pushOriginOrderExecutorService = executor.getThreadPoolExecutor();
//执行业务逻辑
pushOriginOrderExecutorService.shutdown();
pushOriginOrderExecutorService.awaitTermination(1, TimeUnit.HOURS);

其他方法实现:

1、使用CountDownLatch

int nThreads = 10; // 子线程数量
CountDownLatch latch = new CountDownLatch(nThreads);

for (int i = 0; i < nThreads; i++) {
    executor.execute(() -> {
        // 执行任务
        latch.countDown(); // 子线程执行完毕后调用countDown
    });
}

try {
    latch.await(); // 等待所有子线程执行完毕
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}

2、使用CompletableFuture

List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < nThreads; i++) {
    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        // 执行任务
    }, executor);
    futures.add(future);
}

CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
allOf.join(); // 等待所有任务执行完毕

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值