测试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(); // 等待所有任务执行完毕