Java 我无法通过ExecutorService获得RejectedExecutionException
我创建Scheduler以处理被拒绝的执行异常:Java 我无法通过ExecutorService获得RejectedExecutionException,java,executorservice,executor,Java,Executorservice,Executor,我创建Scheduler以处理被拒绝的执行异常: @Component public class TestScheduler { private final TestService testService; private ExecutorService executorService; public TestScheduler(TestService testService) { this.testService = testService;
@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");
}
}
我等待下一个逻辑:
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
编辑
在real project中,我有以下代码:
@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());
}
}
@PostConstruct
公共void init(){
executorService=Executors.newFixedThreadPool(100,新的CustomizelThreadFactory(“SendRequestExecutor-”);
}
@计划(固定延迟=1000L)
public void sendReady(){
试一试{
List messages=messageService.findReadyToSend();
用于(消息:消息){
message.setStatus(进程中);
Message savedMessage=messageService.save(Message);
executorService.execute(()->sendRequestService.send(savedMessage.getGuid());
}
}捕获(例外e){
log.error(“句柄:+e.getMessage());
}
}
这是否意味着该代码是错误的?因为这可能会发生,所以我会将实体更改为流程中的状态
,当尝试执行时-如果executorService
已满,我不会得到异常,并且executorService
不会执行我的任务 RejectedExecutionException
将被抛出到您的溢出任务队列中(现在是未绑定的),而您希望在安排更多任务时抛出它(将其放入可能未绑定的队列中)然后您就有了工作者——这是不存在的,因为这是工作者的一种目的——来构建队列并从中执行
要测试错误处理,可以模拟您的执行者并在任务提交时抛出异常(首选),或者使用有限、有界、非阻塞队列作为您的执行者的支持队列
使用mock是最简单的方法。
RejectedExecutionException
将向您抛出溢出任务队列(现在是未绑定的),而您希望在安排更多任务时抛出它(将其放入可能未绑定的队列)然后您就有了工作者——这是不存在的,因为这是工作者的一种目的——来构建队列并从中执行
要测试错误处理,可以模拟您的执行者并在任务提交时抛出异常(首选),或者使用有限、有界、非阻塞队列作为您的执行者的支持队列
使用mock是最简单的方法。定义执行器时涉及两个方面
newFixedThreadPool
创建的执行器使用无界队列,因此不会出现异常新线程池执行器(5,
5.
2000L,
TimeUnit.ms,
新的ArrayBlockingQueue(5,true),
新的ThreadPoolExecutor.CallerRunPolicy());
定义执行者时涉及两个方面
newFixedThreadPool
创建的执行器使用无界队列,因此不会出现异常新线程池执行器(5,
5.
2000L,
TimeUnit.ms,
新的ArrayBlockingQueue(5,true),
新的ThreadPoolExecutor.CallerRunPolicy());
我提出了一个问题。看please@ip696代码没有错。该executor服务定义使用一个无界任务队列,因此不会出现异常。如果您想获得溢出异常,请更改executor的创建方式。aaa,似乎,我理解您的意思)这在我看来是一个来自5个线程的池,但队列不受限制。当池已满时—新线程被放入队列中,当它们完成时,会从队列中替换它们吗?那么在这种情况下,如果我的调度程序将超过执行器很多,我只能得到内存溢出(执行器队列将非常大)?是的,这是正确的,任务被添加到(无界)任务队列并等待可用线程。它只能在内存不足的情况下失败。我提出了一个问题。看please@ip696代码没有错。该executor服务定义使用一个无界任务队列,因此不会出现异常。如果您想获得溢出异常,请更改executor的创建方式。aaa,似乎,我理解您的意思)这在我看来是一个来自5个线程的池,但队列不受限制。当池已满时—新线程被放入队列中,当它们完成时,会从队列中替换它们吗?
new ThreadPoolExecutor(5,
5,
2000L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(5, true),
new ThreadPoolExecutor.CallerRunsPolicy());