Java ThreadPoolExecutor的线程是否使用with PriorityBlockingQueue并发运行
我正在使用java ThreadPoolExecutor来运行并发线程执行。我使用ArrayBlockingQueue将线程保持在队列中。但现在需求已经改变,我需要添加线程运行时间(没有大小限制),并且应该优先考虑。 因此,我决定使用PriorityBlockingQueue,而不是带有一些比较逻辑的ArrayBlockingQueue。 在使用PriorityBlockingQueue之后,线程将依次运行,而不是并发运行。一次只运行一个线程,而不是活动线程数。 请让我知道,如果有任何人有任何建议来解决这个问题,并实现我的要求(线程应在运行时添加到池中,it执行应基于优先级) 我的演示代码:Java ThreadPoolExecutor的线程是否使用with PriorityBlockingQueue并发运行,java,java.util.concurrent,threadpoolexecutor,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();
//RejectedExecutionHandler实现
RejectedExecutionHandlerImpl rejectionHandler=新的RejectedExecutionHandlerImpl();
//获取要使用的ThreadFactory实现
BlockingQueue=new PriorityBlockingQueue(50,ThreadComparator.getComparator());
ThreadPoolExecutor executorPool=新的ThreadPoolExecutor(1,activeThread,10,TimeUnit.SECONDS,queue,threadFactory,rejectionHandler);
//启动监视线程
MyMonitorThread monitor=新的MyMonitorThread(executorPool,20,“Demo”);
线程监视器线程=新线程(监视器);
monitorThread.start();
for(int i=0;i
公共抽象类ThreadComparator实现Comparator{
公共静态比较器getComparator(){
返回新的比较器(){
@凌驾
公共整数比较(可运行t1,可运行t2){
CompareToBuilder compare=新建CompareToBuilder();
MyThread mt1=(MyThread)t1;
MyThread mt2=(MyThread)t2;
append(mt1.getPriority(),mt2.getPriority());
返回compare.toComparison();
}
};
}
}这是工作队列无限的
ThreadPoolExecutor
的预期行为
引用:
核心池和最大池大小ThreadPoolExecutor将自动调整池大小[…]。 在方法execute(Runnable)中提交新任务时,更少 当corePoolSize线程正在运行时,将创建一个新线程以 处理请求,即使其他工作线程处于空闲状态。如果有 大于corePoolSize但小于maximumPoolSize线程 运行时,仅当队列已满时才会创建新线程。[……] 由于您将
corePoolSize
定义为1
,并且PriorityBlockingQueue
本质上是一个无界队列(永远不会变满),因此您将永远不会有多个线程
解决方法是将
corePoolSize
调整到所需的线程数。抽象地回答这样的问题真的很难。从ArrayBlockingQueue更改为PriorityBlockingQueue不应影响应用程序的并发性。如果您共享您看到的行为的一部分,将更容易提供帮助。我希望上述代码将更容易理解该行为。我可以将corePoolSize和maximumPoolSize设置为相等吗?@PrakashKumar当然,唯一的要求是corePoolSize不能大于maximumPoolSize。从文档中可以看出:“通过将corePoolSize和maximumPoolSize设置为相同,您可以创建一个固定大小的线程池。”如果在执行时在队列中添加更多线程,我需要问一个问题。线程池从队列中随机选取具有相同优先级的线程。我可以用同样的优先级进行排序吗。表示池按顺序拾取线程以获得相等的priority@PrakashKumarJavaDoc for PriorityBlockingQueue()有一个示例类(FIFOEntry
),您可以根据需要采用该类(以相同的插入顺序执行任务)。基本上,它可以归结为在任务中添加一个“timestamp”字段,在插入时为任务分配递增的数字。谢谢你的建议,我已经实现了我想要的一切。现在我需要为我的研发做更多的更改,寻找解决方案/演示/代码来分别/独立地运行多个作业。我的要求如下:所有作业都有一个线程池,我可以管理活动的运行线程(增加或减少运行时间),以充分利用CPU核心。是否可能,是否有人有建议/解决方案?
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();
}
};
}