ThreadPoolExecutor配置


我头上有犄角
2025-03-09 10:59:14 (29天前)



政策
</跨度>
。但是我想知道这是否会影响吞吐量(因为每次调用者都会运行

政策
</跨度>
调用线程池任务可能会完成并闲置一段时间)。

另一个想法是使用ArrayBlockingQueue修复 线程池,但我实际上并不确定它的行为。我希望这意味着

执行者
</跨度>
如果小于coreThread大小,则更喜欢创建线程,然后排队,如果是

5 条回复
  1. 0# 部落用户 | 2019-08-31 10-32



    我想这是另一个答案,因为它对同一个问题有不同的解决方案。



    您只能使用ThreadPoolExecutor和Semaphore。信号量将使用您希望在队列中允许的最大数量创建,并且在每个线程完成执行后,您将调用release(beforeExecute,即项目从队列中取出时)




    1. Semaphore semaphore = new Semaphore(1000);
      ThreadPoolExecutor executor = new ThreadPoolExecutor(5,10,60,TimeUnit.SECONDS,new LinkedBlockingQueue()){
      protected void beforeExecute(Runnable r, Throwable t) {
      semaphore.release();
      }
      }

    2. public void doSubmit(Runnable r){
      sempahore.acquire();
      executor.submit(r);
      }

    3. </code>


    所以这里所有线程都将暂停,直到有可用的许可证(队列中的条目)。


  2. 1# 妖邪 | 2019-08-31 10-32



    只要队列长度太长,您就可以让生产者暂停。



    这样的事情将等待任务队列的大小限制为MAX_LEN。




    1. ExecutorService service =
      Queue workQ = // queue of service.
      BufferedReader br =
      String line;
      while((line = br.readline()) != null) {
      service.submit(new ProcessLineRunnable(line));
      while(workQ.size() > MAX_LEN) Thread.sleep(1);
      }

    2. </code>

  3. 2# star*위위 | 2019-08-31 10-32



    如果单个线程正在发出所有请求,那么无限制队列将根据您的喜好进行阻塞,而不会产生队列增长的负面影响。



    如果多个线程发出请求,那么具有调用者运行策略的固定池应该可以按您的需要工作。池中的其余线程将由其他请求线程保持活动状态。


  4. 3# 荧惑 | 2019-08-31 10-32



    当当前正在使用所有线程时,ThreadPoolExecutor将创建更多线程。这意味着队列可以为空,但如果所有线程都在运行先前的任务,则新任务将创建一个新线程,直到达到最大值。



    如果队列已满并且线程都已饱和,则ThreadPoolExecutor将实际拒绝该任务并抛出一个

    RejectedExecutionException

    。因此,使用BlockingQueue实际上不会产生预期的结果。



    如果要限制当前队列中的任务数,可以使用ExecutorCompletionService和后备队列。




    1. //core 5 max 10 with 60 second idle time
      ThreadPoolExecutor executor = new ThreadPoolExecutor(5,10,60,TimeUnit.SECONDS,new LinkedBlockingQueue());
      ExecutorCompletionService completionService = new ExecutorCompletionService(executor);
      private final static int MAX_IN_QUEUE = 1000;

    2. public void doSubmit(Runnable r){
      while(executor.getQueue().size() >= MAX_IN_QUEUE)
      completionService.poll(100,TimeUnit.MILLISECONDS);
      completionService.submit(r);
      }

    3. </code>


    这具有必须持续等待元素完成的明显副作用。我在条件上循环,因为在进入区块后,while的可能竞争条件实际上是真正的非物质性。



    当然还有多个提交的竞争条件,但它应该足够节流以防止队列过度拥挤。这可以通过简单地同步来解决

    doSubmit

    方法。


登录 后才能参与评论