1.第一种方法
@Slf4j
public class ProdOverviewCounter {
private static final ExecutorService threadPool;
private static final Service service;
static {
Service=SpringContextHolder.getBean(Service.class);
threadPool = new ThreadPoolExecutor(
4,
8,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1024),
new ThreadFactoryBuilder().setNameFormat("Txn-menu-prod-overview-counter-pool-%d").build()
);
//钩子方法关闭当前线程池任务
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
threadPool.isShutdown();//新任务无法提交
try {
if(threadPool.awaitTermination(60,TimeUnit.SECONDS)){//等待未完成的任务
threadPool.isShutdown();//取消当前执行的任务
log.warn("Interrupt the worker, which may cause some task inconsistent. Please check the biz logs.");
// 等待任务取消的响应
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS))
log.error("Thread pool can't be shutdown even with interrupting worker threads, which may cause some task inconsistent. Please check the biz logs.");
}
} catch (InterruptedException e) {
// 重新取消当前线程进行中断
threadPool.shutdownNow();
log.error("The current server thread is interrupted when it is trying to stop the worker threads. This may leave an inconcistent state. Please check the biz logs.");
// 保留中断状态
Thread.currentThread().interrupt();
}
log.info("Txn-prod-overview-counter-pool is about to shutdown...");
}
}));
}
private final Map<String, Object> result;
private final QueryParams qps;
private final CountDownLatch latch;
public ProdOverviewCounter(QueryParams qps) {
this.result = new HashMap<>(5);
this.qps = qps;
this.latch = new CountDownLatch(4);
}
private QueryParams newExclusiveQps(QueryParams qps) {
QueryParams exclusive = new QueryParams();
BeanUtils.copyProperties(qps, exclusive);
return exclusive;
}
//方法1
private void asyncMethod1() {
threadPool.execute(() -> {
latch.countDown();
});
}
//方法2
private void asyncMethod2() {
threadPool.execute(() -> {
latch.countDown();
});
}
//方法3
private void asyncMethod3() {
threadPool.execute(() -> {
latch.countDown();
});
}
//方法4
private void asyncMethod4() {
threadPool.execute(() -> {
latch.countDown();
});
}
public Map<String, Object> count() {
//方法1
asyncMethod1();
//方法2
asyncMethod2();
//方法3
asyncMethod3();
//方法4
asyncMethod4();
await();
return result;
}
private void await() {
try {
//等待所有4个指标查询并计算完毕
if (!latch.await(60 * 1000L, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Timeout before the count reached zero in prodOverviewCounter(..)");
}
} catch (InterruptedException e) {
log.warn("Main thread interrupted in prodOverviewCounter(..)", e);
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
}
2.第二种方法
private ExecutorService threadPool;
@PostConstruct
public void init() {
threadPool = new ThreadPoolExecutor(
8,
8,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1024),
new ThreadFactoryBuilder().setDaemon(true).setNameFormat("accHome-pool-%d").build()
);
}
CompletableFuture<?>[] tasks = new CompletableFuture[length];//初始化线程数量
for (int i = 0; i < length; i++) {
String accType = accTypes[i];
tasks[i] = CompletableFuture.supplyAsync(() -> testmethod(), threadPool)
.thenAccept(testMethod2(param1,param2));
}
CompletableFuture.allOf(tasks).join();//等待所有异步线程返回