Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 更改线程池执行器_Java_Multithreading_Java.util.concurrent_Threadpoolexecutor - Fatal编程技术网

Java 更改线程池执行器

Java 更改线程池执行器,java,multithreading,java.util.concurrent,threadpoolexecutor,Java,Multithreading,Java.util.concurrent,Threadpoolexecutor,如以下链接所述:- 我将队列实现更改为在输入元素后返回false。 因此,每当将新任务插入队列时,都会为其创建一个新线程 但是,当我大规模运行下面的实现(Bis系统测试)时,日志记录者遇到了一个新问题 当一个任务来执行时,它会被插入到队列中,当队列返回false时,会创建一个新线程来执行它。不会拾取池中当前存在的空闲线程。原因是任务从从从队列中拾取任务的getTask()方法分配给空闲线程。因此,我的问题是如何更改此行为,以便在线程空闲时如何确保为空闲线程分配执行任务,而不是创建新线程???

如以下链接所述:-

我将队列实现更改为在输入元素后返回false。 因此,每当将新任务插入队列时,都会为其创建一个新线程

但是,当我大规模运行下面的实现(Bis系统测试)时,日志记录者遇到了一个新问题

当一个任务来执行时,它会被插入到队列中,当队列返回false时,会创建一个新线程来执行它。不会拾取池中当前存在的空闲线程。原因是任务从从从队列中拾取任务的
getTask()
方法分配给空闲线程。因此,我的问题是如何更改此行为,以便在线程空闲时如何确保为空闲线程分配执行任务,而不是创建新线程???

下面的输出将更加清楚:-

Task 46 ends
Active Count: 0 Pool Size : 3 Idle Count: 3 Queue Size: 0
Task 47 ends
Active Count: 0 Pool Size : 3 Idle Count: 3 Queue Size: 0
Task 48 ends
Active Count: 0 Pool Size : 3 Idle Count: 3 Queue Size: 0
Active Count: 1 Pool Size : 4 Idle Count: 3 Queue Size: 0
Task 49 ends
Active Count: 2 Pool Size : 5 Idle Count: 3 Queue Size: 0
Task 50 ends
Active Count: 2 Pool Size : 5 Idle Count: 3 Queue Size: 0
代码文件如下所示:-

ThreadPoolExecutor是java 1.5版本,因为我们在服务器计算机上使用1.5,无法升级

线程池执行器:-

 public void execute(Runnable command) {
    System.out.println("Active Count: " + getActiveCount()
            + " Pool Size : " + getPoolSize() + " Idle Count: "
            + (getPoolSize() - getActiveCount())+" Queue Size: "+getQueue().size());
          if (command == null)
              throw new NullPointerException();
          for (;;) {
              if (runState != RUNNING) {
                  reject(command);
                  return;
              }
              if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
                  return;
              if (workQueue.offer(command))
                  return;
              int status = addIfUnderMaximumPoolSize(command);
              if (status > 0)      // created new thread
                  return;
              if (status == 0) {   // failed to create thread
                  reject(command);
                  return;
              }
              // Retry if created a new thread but it is busy with another task
          }
      }
public class CustomBlockingQueue<E> extends LinkedBlockingQueue<E> 
{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public CustomBlockingQueue() {
    super(Integer.MAX_VALUE);
    }

    public boolean offer(E e) {
       return false;
    }

}
public void execute(Runnable命令){
System.out.println(“活动计数:”+getActiveCount()
+池大小:“+getPoolSize()+”空闲计数:
+(getPoolSize()-getActiveCount())+“队列大小:”+getQueue().Size());
如果(命令==null)
抛出新的NullPointerException();
对于(;;){
如果(运行状态!=正在运行){
拒绝(命令);
返回;
}
if(poolSize0)//已创建新线程
返回;
如果(状态==0){//创建线程失败
拒绝(命令);
返回;
}
//如果创建了一个新线程,但它正忙于另一个任务,请重试
}
}
LinkedBlockingQueue:-

 public void execute(Runnable command) {
    System.out.println("Active Count: " + getActiveCount()
            + " Pool Size : " + getPoolSize() + " Idle Count: "
            + (getPoolSize() - getActiveCount())+" Queue Size: "+getQueue().size());
          if (command == null)
              throw new NullPointerException();
          for (;;) {
              if (runState != RUNNING) {
                  reject(command);
                  return;
              }
              if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
                  return;
              if (workQueue.offer(command))
                  return;
              int status = addIfUnderMaximumPoolSize(command);
              if (status > 0)      // created new thread
                  return;
              if (status == 0) {   // failed to create thread
                  reject(command);
                  return;
              }
              // Retry if created a new thread but it is busy with another task
          }
      }
public class CustomBlockingQueue<E> extends LinkedBlockingQueue<E> 
{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public CustomBlockingQueue() {
    super(Integer.MAX_VALUE);
    }

    public boolean offer(E e) {
       return false;
    }

}
公共类CustomBlockingQueue扩展LinkedBlockingQueue
{
/**
* 
*/
私有静态最终长serialVersionUID=1L;
公共CustomBlockingQueue(){
super(整数最大值);
}
公共布尔报价(E){
返回false;
}
}
在拒绝处理程序中,我们正在调用队列的put方法,但尚未覆盖该方法

呼叫执行器

   final CustomThreadPoolExecutor tpe = new CustomThreadPoolExecutor(3, 8, 0L, TimeUnit.MILLISECONDS, new MediationBlockingQueue<Runnable>(), new MediationRejectionHandler());

private static final int TASK_COUNT = 100;

 for (int i = 0; i < TASK_COUNT; i++) {

......
tpe.execute(new Task(i));
.....
}
final CustomThreadPoolExecutor tpe=new CustomThreadPoolExecutor(3,8,0L,TimeUnit.ms,new MediationBlockingQueue(),new MediationRejectionHandler());
私有静态最终整数任务计数=100;
对于(int i=0;i

我们正在调用执行器,核心池大小为3,最大池大小为8,并为任务使用无界链接阻塞队列

实现“先启动后排队,但更喜欢现有线程”行为的最简单方法是使用。当且仅当已经有等待的接收者时,它才会接受提供的物品。因此,空闲线程将获取项目,一旦没有空闲线程,
ThreadPoolExecutor
将启动新线程

唯一的缺点是,一旦启动了所有线程,就不能简单地将挂起的项放入队列,因为它没有容量。因此,您要么必须接受提交者被阻止,要么需要另一个队列将挂起的任务放入其中,或者需要另一个后台线程将这些挂起的项目放入同步队列。这个额外的线程不会影响性能,因为它大部分时间都被阻塞在这两个队列中

class QueuingRejectionHandler implements RejectedExecutionHandler {

  final ExecutorService processPending=Executors.newSingleThreadExecutor();

  public void rejectedExecution(
      final Runnable r, final ThreadPoolExecutor executor) {
    processPending.execute(new Runnable() {
      public void run() {
        executor.execute(r);
      }
    });
  }
}

ThreadPoolExecutor e=新的ThreadPoolExecutor(
corePoolSize、maximumPoolSize、keepAliveTime、单位、,
新建SynchronousQueue(),新建QueuingRejectionHandler());
格雷给出的解决方案非常棒,但我遇到了和你一样的问题,也就是说,理想线程并没有被用来选择新任务,但新线程是在poolSize小于maxPoolSize的情况下创建的

所以,我试图调整ThreadPoolExecutor本身的功能,通过复制完整的类(这不是一个好主意,但找不到任何其他解决方案),并使用ThreadPoolExecutor扩展它并重写execute方法

方法如下:

public void execute(Runnable command)
{
 System.out.println("ActiveCount : " + this.getActiveCount()
            + " PoolSize : " + this.getPoolSize() + " QueueSize : "
            + this.getQueue().size());

if (command == null)
    throw new NullPointerException();
for (;;)
{
    if (runState != RUNNING)
    {
    reject(command);
    return;
    }
    if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
    return;
    //Now, it will never offer to queue but will go further for thread creation.
    //if (workQueue.offer(command))
    //return;


    //This check is introduced to utilized ideal threads instead of creating new thread 
    //for incoming tasks.
    //Example : coreSize = 3, maxPoolSize = 8.
    //activeCount = 4, and PoolSize = 5, so 1 thread is ideal Currently queue is empty. 
    //When new task comes, it will offer that to queue, and getTask() will take care and execute the task.
    //But if new task comes, before ideal thread takes task from queue, 
    //activeCount = 4, and PoolSize = 5, so 1 thread is ideal Currently queue size = 1.
    //this check fails and new thread is created if poolsize under max size or 
    //task is added to queue through rejection handler.

    if ((this.getPoolSize() - this.getActiveCount()) > 0 && 
        (this.getPoolSize() - this.getActiveCount() - workQueue.size()) > 0)
    {
    workQueue.offer(command);
    return;
    }
    int status = addIfUnderMaximumPoolSize(command);
    if (status > 0) // created new thread
    return;
    if (status == 0)
    { // failed to create thread
    reject(command);
    return;
    }
    // Retry if created a new thread but it is busy with another task
}
}
public void execute(Runnable命令)
{
System.out.println(“ActiveCount:+this.getActiveCount()
+PoolSize:“+this.getPoolSize()+”队列大小:
+这个.getQueue().size());
如果(命令==null)
抛出新的NullPointerException();
对于(;;)
{
如果(运行状态!=正在运行)
{
拒绝(命令);
返回;
}
if(poolSize0&&
(this.getPoolSize()-this.getActiveCount()-workQueue.size())>0)
{
workQueue.offer(命令);
返回;
}
int status=addIfUnderMaximumPoolSize(命令);
public boolean offer(Runnable e) {
    /*
     * Offer it to the queue if there is 1 or 0 items already queued, else
     * return false so the TPE will add another thread.
     */
    if (size() <= 1) {
        return super.offer(e);
    } else {
        return false;
    }
}
public static ExecutorService newWorkStealingPool()
ExecutorService executorService = Executors.newWorkStealingPool();