1. 完整使用案例
private static final int CPUS = Runtime.getRuntime().availableProcessors();
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(CPUS * 3, CPUS * 3, 1L, HOURS, new LinkedBlockingDeque<>(6000), new ThreadFactoryBuilder().setNameFormat("test-executor-pool-%d").build());
List<User> list1 = new ArrayList<>();
List<User> list2 = new ArrayList<>();
if (CollectionUtils.isNotEmpty(list1)) {
CountDownLatch list1Latch = new CountDownLatch(list1.size());
for (User user : list1) {
executor.execute(() -> {
try {
} catch (Exception ex) {
log.error(">>> 线程list1Latch编号: {}, 线程异常:{}", list1Latch.getCount(), getStackTrace(ex));
} finally {
list1Latch.countDown();
}
});
}
try {
list1Latch.await(3, TimeUnit.MINUTES);
} catch (InterruptedException ex) {
log.error("线程处理超过3分钟, 定义为执行失败");
throw new Exception("处理失败");
}
}
if (CollectionUtils.isNotEmpty(list2)) {
CountDownLatch list2Latch = new CountDownLatch(list2.size());
}
2. 自己摸索的等待线程实现
private static final int CPUS = Runtime.getRuntime().availableProcessors();
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(CPUS * 3, CPUS * 3, 1L, HOURS, new LinkedBlockingDeque<>(6000), new ThreadFactoryBuilder().setNameFormat("test-executor-pool-%d").build());
@Test
public void 等待线程测试() throws Exception {
List<String> result = new ArrayList<>();
List<String> strList = new ArrayList<>();
strList.add("100"); strList.add("200"); strList.add("300"); strList.add("400"); strList.add("500");
strList.add("600"); strList.add("700"); strList.add("800"); strList.add("900"); strList.add("1000"); strList.add("1100");
System.out.println("strList.size = " + strList.size() + "; strList = " + strList);
CountDownLatch countDownLatch = new CountDownLatch(strList.size());
System.out.println("count = " + countDownLatch.getCount());
List<String> collect1 = strList.stream().filter(s -> Integer.parseInt(s) <= 500).collect(toList());
System.out.println("collect1.size = " + collect1.size() + "; collect1 = " + collect1);
List<String> collect2 = strList.stream().filter(s -> Integer.parseInt(s) > 500).collect(toList());
System.out.println("collect2.size = " + collect2.size() + "; collect2 = " + collect2);
for (String s : collect1) {
executor.execute(() -> {
try {
System.out.println("[1] 线程内 s = " + s);
result.add(s);
} catch (Exception ex) {
System.out.println("模版文件数据解析对应的countDownLatch编号 = " + countDownLatch.getCount());
} finally {
countDownLatch.countDown();
System.out.println("[1] latch1 = " + countDownLatch);
}
});
}
long l1 = strList.size() - collect1.size();
waitAndCheck(l1, countDownLatch);
System.out.println("第一个线程结束的 result = " + result);
System.out.println("------------------------------");
for (String s : collect2) {
executor.execute(() -> {
try {
System.out.println("[2] 线程内 s = " + s);
result.add(s);
} catch (Exception ex) {
System.out.println("模版文件数据解析对应的countDownLatch编号 = " + countDownLatch.getCount());
} finally {
countDownLatch.countDown();
System.out.println("[2] countDownLatch = " + countDownLatch);
}
});
}
waitAndCheck(0L, countDownLatch);
System.out.println("第二个线程结束的 result = " + result);
}
private void waitAndCheck(long checkNum, CountDownLatch latch) throws Exception {
boolean overtime = false;
long startTime = System.currentTimeMillis();
while (true) {
if (latch.getCount() == checkNum) {
break;
}
long endTime = System.currentTimeMillis();
if (endTime - startTime >= 30000) {
overtime = true;
break;
}
}
if (overtime) {
throw new Exception("EXCEL处理超时, 请减少数据量后重试或联系管理员!");
}
}