ThreadPoolExecutor的线程是否不会与PriorityBlockingQueue

时间:2018-07-02 02:51:00

标签: java java.util.concurrent threadpoolexecutor

我正在使用java ThreadPoolExecutor运行并发线程执行。我使用ArrayBlockingQueue将线程保持在队列中。但是现在需求已更改,我需要添加线程运行时间(无大小限制),因此应该优先处理。 因此,我决定使用带有一些比较逻辑的PriorityBlockingQueue而不是ArrayBlockingQueue。 使用PriorityBlockingQueue后,线程将依次运行,而不是一个接一个地运行。一次仅运行一个线程,而不管活动线程的数量如何。 请让我知道是否有人建议解决此问题并达到我的要求(线程应在运行时添加到池中,并且执行应基于优先级)。

我的演示代码:

//RejectedExecutionHandler implementation
    RejectedExecutionHandlerImpl rejectionHandler = new RejectedExecutionHandlerImpl();
    //Get the ThreadFactory implementation to use
    BlockingQueue<Runnable> queue = new PriorityBlockingQueue<Runnable>(50, ThreadComparator.getComparator());
    ThreadPoolExecutor executorPool = new ThreadPoolExecutor(1, activeThread, 10, TimeUnit.SECONDS, queue, threadFactory, rejectionHandler);
    //start the monitoring thread
    MyMonitorThread monitor = new MyMonitorThread(executorPool, 20, "Demo");
    Thread monitorThread = new Thread(monitor);
    monitorThread.start();

    for (int i = 0; i < totalThead; i++) {
        int prio = i % 3 == 0 ? 3 : 5;
        executorPool.execute(new MyThread("Thread-" + i, prio));        
    }

    // Inserting more threads in between concurrent execution.
    try {
        Thread.sleep(40000);
        for (int j = 101; j < 110; j++) {
            executorPool.execute(new MyThread("Thread-" + j, 2));
        }
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }


    while(executorPool.getActiveCount() != 0) {
        try {
            Thread.sleep(10000); 
        } catch (InterruptedException e) {
            System.out.println("Error while thread sleeping: " + e);
        }
    }
    //shut down the pool
    executorPool.shutdown();
    //shut down the monitor thread
    try {
        Thread.sleep(5000); 
    } catch (InterruptedException e) {
        System.out.println("Error while thread sleeping: " + e);
    }
    monitor.shutdown();

 public abstract class ThreadComparator implements Comparator<Runnable>{

public static Comparator<Runnable> getComparator() {
    return new Comparator<Runnable>() {
        @Override
        public int compare(Runnable t1, Runnable t2) {
            CompareToBuilder compare = new CompareToBuilder();
            MyThread mt1 = (MyThread) t1;
            MyThread mt2 = (MyThread) t2;
            compare.append(mt1.getPriority(), mt2.getPriority());
            return compare.toComparison();
        }
    };
}

}

1 个答案:

答案 0 :(得分:0)

这是ThreadPoolExecutor的工作队列不受限制的预期行为。

引用ThreadPoolExecutor JavaDoc

  

核心和最大池大小
  ThreadPoolExecutor将自动调整池大小[..]。   在方法execute(Runnable)中提交新任务时,更少   超过corePoolSize线程正在运行时,将创建一个新线程   处理请求,即使其他工作线程处于空闲状态也是如此。如果有   大于corePoolSize但小于maximumPoolSize线程   在运行时,仅当队列已满时才会创建新线程。 [...]

由于将corePoolSize定义为1,并且PriorityBlockingQueue本质上是一个无界队列(永远不会变满),因此您将永远不会有多个线程。

解决方法是将corePoolSize调整为所需的线程数。