我无法通过 ExecutorService 获得

我为 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");

    }

}

我等待下一个逻辑:

  1. 调度程序调用executorService.execute(testService::print)5 次

  2. 每个testService::print将执行 70 秒

  3. 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


拉莫斯之舞
浏览 142回答 2
2回答

猛跑小猪

定义执行器时涉及两个方面。执行程序将使用的线程数。这限制了执行程序可以运行的并发任务的数量。这是您通过Executors.newFixedThreadPool(5).底层任务提交队列的大小。这限制了底层队列可以存储的任务数量,直到它抛出异常。创建的执行器newFixedThreadPool使用无界队列,因此您不会收到异常。您可以通过如下创建自己的执行程序服务并向其提交 11 个任务(5 个使用所有线程,5 个填充底层任务队列和 1 个溢出它)来实现您想要的行为。new&nbsp;ThreadPoolExecutor(5,&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5,&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2000L,&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TimeUnit.MILLISECONDS,&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;ArrayBlockingQueue<Runnable>(5,&nbsp;true),&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;ThreadPoolExecutor.CallerRunsPolicy());

牛魔王的故事

RejectedExecutionException将被抛出您溢出任务队列(并且现在是未绑定的),而您希望在安排更多任务时抛出它(将其放入可能是无限制的队列)然后您有工作人员 - 这是废话,因为这是一种目的worker - 构建队列并从中执行。要测试错误处理,请模拟您的执行程序并在任务提交时抛出异常(最好),或者使用有限的、有界的、非阻塞队列作为您的执行程序的后备队列。使用模拟是最简单的方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java