我为 RejectedExecutionException 的测试处理创建了调度程序:@Componentpublic class TestScheduler { private final TestService testService; private ExecutorService executorService; public TestScheduler(TestService testService) { this.testService = testService; } @PostConstruct public void init() { executorService = Executors.newFixedThreadPool(5); } @Scheduled(fixedRate = 10L) public void test() { System.out.println("test"); executorService.execute(testService::print); }}和延迟 70 秒的服务:@Componentpublic class TestService { public void print() { System.out.println("print start"); try { TimeUnit.SECONDS.sleep(70); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("print end"); }}我等待下一个逻辑:调度程序调用executorService.execute(testService::print)5 次每个testService::print将执行 70 秒当execute方法第六次调用我得到RejectedExecutionException但我没有得到异常。我有这个日志:testprint start2018-10-22 11:26:45.543 INFO 5960 --- [ main] c.e.s.SchedullerExceptionsApplication : Started SchedullerExceptionsApplication in 0.661 seconds (JVM running for 1.108)testprint starttestprint starttestprint starttestprint starttest...70 seconds print test
2 回答
猛跑小猪
TA贡献1858条经验 获得超8个赞
定义执行器时涉及两个方面。
执行程序将使用的线程数。这限制了执行程序可以运行的并发任务的数量。这是您通过
Executors.newFixedThreadPool(5)
.底层任务提交队列的大小。这限制了底层队列可以存储的任务数量,直到它抛出异常。创建的执行器
newFixedThreadPool
使用无界队列,因此您不会收到异常。
您可以通过如下创建自己的执行程序服务并向其提交 11 个任务(5 个使用所有线程,5 个填充底层任务队列和 1 个溢出它)来实现您想要的行为。
new ThreadPoolExecutor(5, 5, 2000L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5, true), new ThreadPoolExecutor.CallerRunsPolicy());
牛魔王的故事
TA贡献1830条经验 获得超3个赞
RejectedExecutionException
将被抛出您溢出任务队列(并且现在是未绑定的),而您希望在安排更多任务时抛出它(将其放入可能是无限制的队列)然后您有工作人员 - 这是废话,因为这是一种目的worker - 构建队列并从中执行。
要测试错误处理,请模拟您的执行程序并在任务提交时抛出异常(最好),或者使用有限的、有界的、非阻塞队列作为您的执行程序的后备队列。
使用模拟是最简单的方法。
添加回答
举报
0/150
提交
取消