final static ExecutorService executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<>());
public static void main(String[] args) {
// 模拟 1000 并发请求,会发现下面的 get 时 会有几率报错。在压测的时候,10w 请求,大概 1000+个错误
for (int i = 0; i < 1000; i++) {
executor.submit(() -> {
// 每一个请求真正执行的业务逻辑 demo start
CountDownLatch latch = new CountDownLatch(1);
Future<String> submit = executor.submit(() -> {
latch.countDown();
/**
* 目前猜测,上下两句不是 原子操作
* */
return "abc";
});
try {
latch.await(10, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
// 或者调整 timeout 值,将其调大值,在 10ms 或者更大
System.out.println( submit.get(0, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
// 每一个请求真正执行的业务逻辑 demo end
});
}
}
最后线上改成了这个
future.cancel(true);
if (!future.isCancelled()) {
future.get();
}
1
546L5LiK6ZOt 2021-06-29 23:40:00 +08:00
为啥同时用 CountDownLatch 和 Future ?看你代码,感觉 CountDownLatch 是多余的。
|
2
huskyui OP @546L5LiK6ZOt 用这个,主要是为了在规定时间内返回结果
|
3
546L5LiK6ZOt 2021-06-30 01:07:47 +08:00 via iPhone
@huskyui future 不也可以达到这个效果吗?
|
4
kifile 2021-06-30 09:05:40 +08:00
这个明显就线池处理不过来,超时了呀。不是你说让他 10s 执行完毕,他就能 10s 执行完毕的
|
5
huskyui OP @546L5LiK6ZOt 是多个任务,在规定时间内结束,最后改为了线程池的 invokeAll(taskList,timeout,unit)
|