ExecutorService,用于扩展线程,然后对任务进行排队

azn*_*nan 9 java multithreading executorservice

是否有一个ExecutorService实现行为类似于具有以下特征的线程池?

  1. 总是至少有X个活动线程.
  2. 如果提交任务并且所有活动线程都忙,则启动新线程,最多为Y个线程.
  3. 如果提交任务并且所有Y个线程都忙,则该任务将排队.
  4. 如果未提交任何新任务,则池将缩减为X活动线程.

相当标准的线程池行为.你认为ThreadPoolExecutor会处理这个,但是

executorService = new ThreadPoolExecutor(
    2, 10, // min/max threads
    60, TimeUnit.SECONDS, // time of inactivity before scaling back
    new SynchronousQueue<Runnable>()); // task queue
Run Code Online (Sandbox Code Playgroud)

如果提交的任务超过10个,则会抛出异常.切换到a LinkedBlockingQueue将永远不会扩展到两个最小线程之外,除非你限制大小new LinkedBlockingQueue<Runnable>(20),在这种情况下,将有两个线程处理1-20个任务,2-10个线程处理21-30个任务,并且异常超过30个任务.不漂亮.同时,固定的线程池永远不会缩小非活动线程.

那么,为了得到我所追求的东西,我可以使用其他类型BlockingQueue或小提琴我错过的其他设置吗?是否有另一个ExceutorService更适合的实现(哪个?),或者我最好通过重写execute()方法来自己滚动ThreadPoolExecutor

Bre*_*ken 6

不幸的是,答案是否定的.关于jre中最好的事情就是有效地没有螺纹地板,只有天花板.这可以通过允许核心线程超时来实现.

ThreadPoolExecutor tpe = new ThreadPoolExecutor(10, 10, 60, TimeUnit.Seconds, new LinkedBlockingQueue<Runnable>());
tpe.allowCoreThreadTimeOut(true);
Run Code Online (Sandbox Code Playgroud)

由于核心大小为10,因此在提交任务时将启动新线程,直到10个线程处于活动状态.之后,任务将在LinkedBlockingQueue中排队.如果一个线程处于非活动状态60秒,它将终止.

通过编写实现BlockingQueue和RejectedExecutionHandler的类,可以实现所需的行为,该类在确定任务是应该添加到队列还是被拒绝之前检查ThreadPoolExecutors当前状态.