Java线程池执行器策略&x27;直接切换';排队?
我希望有一个Java线程池执行器策略&x27;直接切换';排队?,java,threadpool,Java,Threadpool,我希望有一个ThreadPoolExecutor,在这里我可以设置corePoolSize和maximumPoolSize,然后队列会立即将任务转移到线程池,从而创建新线程,直到它达到maximumPoolSize,然后开始添加到队列中 有这样的事吗?如果没有,有什么好的理由没有这样的策略吗 本质上,我想要的是任务被提交执行,当它达到一个临界点时,由于线程太多(通过设置maximumPoolSize),它会停止添加新线程,使用线程池并开始排队,如果队列已满,它会拒绝 当负载下降时,它可以开始将未
ThreadPoolExecutor
,在这里我可以设置corePoolSize
和maximumPoolSize
,然后队列会立即将任务转移到线程池,从而创建新线程,直到它达到maximumPoolSize
,然后开始添加到队列中
有这样的事吗?如果没有,有什么好的理由没有这样的策略吗
本质上,我想要的是任务被提交执行,当它达到一个临界点时,由于线程太多(通过设置maximumPoolSize),它会停止添加新线程,使用线程池并开始排队,如果队列已满,它会拒绝
当负载下降时,它可以开始将未使用的线程分解回corePoolSize
在我的应用程序中,这比中列出的“三个一般策略”更有意义。注意:这些实现有些缺陷,而且不确定。使用此代码前,请阅读完整答案和注释。 创建一个工作队列,在执行器低于最大池大小时拒绝项目,并在达到最大池大小后开始接受项目,怎么样 这取决于记录的行为: 如果请求无法排队,则会创建一个新线程,除非 将超过maximumPoolSize,在这种情况下,任务将 拒绝。”
我们通过以下代码找到了该问题的解决方案: 此队列是SynchronousQueue/LinkedBlockingQueue的混合
public class OverflowingSynchronousQueue<E> extends LinkedBlockingQueue<E> {
private static final long serialVersionUID = 1L;
private SynchronousQueue<E> synchronousQueue = new SynchronousQueue<E>();
public OverflowingSynchronousQueue() {
super();
}
public OverflowingSynchronousQueue(int capacity) {
super(capacity);
}
@Override
public boolean offer(E e) {
// Create a new thread or wake an idled thread
return synchronousQueue.offer(e);
}
public boolean offerToOverflowingQueue(E e) {
// Add to queue
return super.offer(e);
}
@Override
public E take() throws InterruptedException {
// Return tasks from queue, if any, without blocking
E task = super.poll();
if (task != null) {
return task;
} else {
// Block on the SynchronousQueue take
return synchronousQueue.take();
}
}
@Override
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
// Return tasks from queue, if any, without blocking
E task = super.poll();
if (task != null) {
return task;
} else {
// Block on the SynchronousQueue poll
return synchronousQueue.poll(timeout, unit);
}
}
公共类溢出同步队列扩展LinkedBlockingQueue{
私有静态最终长serialVersionUID=1L;
private SynchronousQueue SynchronousQueue=新的SynchronousQueue();
公共溢出同步队列(){
超级();
}
公共溢出同步队列(int容量){
超级(容量);
}
@凌驾
公共布尔报价(E){
//创建新线程或唤醒空闲线程
返回synchronousQueue.offer(e);
}
公共布尔型offerToOverflowingQueue(E){
//添加到队列
返回超级报价(e);
}
@凌驾
public E take()抛出InterruptedException{
//从队列返回任务(如果有),不阻塞
E task=super.poll();
如果(任务!=null){
返回任务;
}否则{
//同步队列上的块
返回synchronousQueue.take();
}
}
@凌驾
公共E轮询(长超时,时间单位)抛出InterruptedException{
//从队列返回任务(如果有),不阻塞
E task=super.poll();
如果(任务!=null){
返回任务;
}否则{
//阻止SynchronousQueue轮询
返回synchronousQueue.poll(超时,单位);
}
}
}
为了让它工作,我们需要包装RejectedExecutionHandler,以便在任务被拒绝时调用“OfferToOverflowQueue”
public class OverflowingRejectionPolicyAdapter implements RejectedExecutionHandler {
private OverflowingSynchronousQueue<Runnable> queue;
private RejectedExecutionHandler adaptedRejectedExecutionHandler;
public OverflowingRejectionPolicyAdapter(OverflowingSynchronousQueue<Runnable> queue,
RejectedExecutionHandler adaptedRejectedExecutionHandler)
{
super();
this.queue = queue;
this.adaptedRejectedExecutionHandler = adaptedRejectedExecutionHandler;
}
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (!queue.offerToOverflowingQueue(r)) {
adaptedRejectedExecutionHandler.rejectedExecution(r, executor);
}
}
}
公共类溢出RejectionPolicyAdapter实现RejectedExecutionHandler{
私有溢出同步队列;
私有RejectedExecutionHandler adaptedRejectedExecutionHandler;
公共溢出拒绝策略适配器(溢出同步队列,
RejectedExecutionHandler adaptedRejectedExecutionHandler)
{
超级();
this.queue=队列;
this.adaptedRejectedExecutionHandler=adaptedRejectedExecutionHandler;
}
@凌驾
public void rejectedExecution(可运行的r、线程池执行器执行器){
if(!queue.offerToOverflowingQueue(r)){
adaptedRejectedExecutionHandler.rejectedExecution(r,执行者);
}
}
}
下面是我们如何创建ThreadPoolExecutor的
public static ExecutorService newSaturatingThreadPool(int corePoolSize,
int maxPoolSize,
int maxQueueSize,
long keepAliveTime,
TimeUnit timeUnit,
String threadNamePrefix,
RejectedExecutionHandler rejectedExecutionHandler)
{
OverflowingSynchronousQueue<Runnable> queue = new OverflowingSynchronousQueue<Runnable>(maxQueueSize);
OverflowingRejectionPolicyAdapter rejectionPolicyAdapter = new OverflowingRejectionPolicyAdapter(queue,
rejectedExecutionHandler);
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maxPoolSize,
keepAliveTime,
timeUnit,
queue,
new NamedThreadFactory(threadNamePrefix),
rejectionPolicyAdapter);
return executor;
}
publicstaticexecutorservice newSaturatingThreadPool(int-corePoolSize,
int maxPoolSize,
int maxQueueSize,
长时间,
时间单位时间单位,
字符串threadNamePrefix,
RejectedExecutionHandler RejectedExecutionHandler)
{
OverflowingSynchronousQueue=新的OverflowingSynchronousQueue(maxQueueSize);
OverflowInRejectionPolicyAdapter rejectionPolicyAdapter=新的OverflowInRejectionPolicyAdapter(队列,
拒绝执行处理程序);
ThreadPoolExecutor executor=新的ThreadPoolExecutor(corePoolSize,
最大池大小,
守时,
时间单位,
队列
新命名的ThreadFactory(threadNamePrefix),
拒绝策略适配器);
返还执行人;
}
您的建议是我在现已删除的答案的评论中所说的。无论如何我想你会发现,压倒一切的报价可能会导致问题,因为它没有锁。即使只有3条指令?“或者这么长时间了。”我也在关注同样的事情,我一直试图通过推理解决潜在的问题,但我还没有找到任何答案。我会继续努力仔细考虑。无论如何,接受你的答案。这就是我最后实现的,而不是试图重写ThreadPoolExecutor的执行方法,后者要复杂得多。仅供参考,我还将maximumPoolSize中的缓冲区添加到比实际值低5%的位置,以允许比赛。不是理想的方法,而是Threa的默认行为
public class OverflowingRejectionPolicyAdapter implements RejectedExecutionHandler {
private OverflowingSynchronousQueue<Runnable> queue;
private RejectedExecutionHandler adaptedRejectedExecutionHandler;
public OverflowingRejectionPolicyAdapter(OverflowingSynchronousQueue<Runnable> queue,
RejectedExecutionHandler adaptedRejectedExecutionHandler)
{
super();
this.queue = queue;
this.adaptedRejectedExecutionHandler = adaptedRejectedExecutionHandler;
}
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (!queue.offerToOverflowingQueue(r)) {
adaptedRejectedExecutionHandler.rejectedExecution(r, executor);
}
}
}
public static ExecutorService newSaturatingThreadPool(int corePoolSize,
int maxPoolSize,
int maxQueueSize,
long keepAliveTime,
TimeUnit timeUnit,
String threadNamePrefix,
RejectedExecutionHandler rejectedExecutionHandler)
{
OverflowingSynchronousQueue<Runnable> queue = new OverflowingSynchronousQueue<Runnable>(maxQueueSize);
OverflowingRejectionPolicyAdapter rejectionPolicyAdapter = new OverflowingRejectionPolicyAdapter(queue,
rejectedExecutionHandler);
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maxPoolSize,
keepAliveTime,
timeUnit,
queue,
new NamedThreadFactory(threadNamePrefix),
rejectionPolicyAdapter);
return executor;
}