final static ExecutorService executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUit.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) |