我创建了调度程序来测试RejectedExecutionException的处理:
@Component
public 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秒:
@Component
public 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
但是我没有得到异常。我有这个日志:
test
print start
2018-10-22 11:26:45.543 INFO 5960 --- [ main] c.e.s.SchedullerExceptionsApplication : Started SchedullerExceptionsApplication in 0.661 seconds (JVM running for 1.108)
test
print start
test
print start
test
print start
test
print start
test
...
70 seconds print test
编辑
在实际项目中,我有以下代码:
@PostConstruct
public void init() {
executorService = Executors.newFixedThreadPool(100, new CustomizableThreadFactory("SendRequestExecutor-"));
}
@Scheduled(fixedDelay = 1000L)
public void sendReady() {
try {
List<Message> messages = messageService.findReadyToSend();
for (Message message : messages) {
message.setStatus(IN_PROCESS);
Message savedMessage = messageService.save(message);
executorService.execute(() -> sendRequestService.send(savedMessage.getGuid()));
}
} catch (Exception e) {
log.error("handle: " + e.getMessage());
}
}
这是否意味着此代码是错误的?因为会发生这种情况,所以我将实体更改为状态IN_PROCESS
,并在尝试执行时-如果executorService
已满,我不会出现异常,而executorService
不会执行我的任务吗?
答案 0 :(得分:2)
定义执行程序时涉及两个方面。
Executors.newFixedThreadPool(5)
进行的设置。newFixedThreadPool
创建的执行程序使用无限制的队列,因此不会出现异常。您可以通过如下创建自己的执行程序服务并向其提交11个任务(5个使用所有线程,5个填充底层任务队列和1个溢出任务)来实现所需的行为。
new ThreadPoolExecutor(5,
5,
2000L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(5, true),
new ThreadPoolExecutor.CallerRunsPolicy());
答案 1 :(得分:0)
RejectedExecutionException
将被抛出给您溢出任务队列(目前尚未绑定),而您希望在安排更多任务时将其抛出(放入可能不受限制的队列) ),那么您就有了工作人员-多数民众赞成在这是工作人员的目的-建立队列并从中执行。
要测试错误处理,请模拟执行器并在任务提交时抛出异常(最好),或者使用有限,有界,无阻塞的队列作为执行器的后备队列。
使用模拟是最简单的方法。