Java 如何创建一个ThreadPoolExecutor,根据需要创建线程并在适用时使其过期?

Java 如何创建一个ThreadPoolExecutor,根据需要创建线程并在适用时使其过期?,java,executorservice,threadpoolexecutor,Java,Executorservice,Threadpoolexecutor,我的用例: 为线程池设置最小大小“N”,这意味着“N”个线程在执行器启动后始终可用 为线程池设置最大大小“M” 当所有“M”线程都忙时,传入任务应排队 根据空闲状态的超时使(M-N)线程过期 我相信HttpClient后面的池管理器也可以进行类似的设置。我正在尝试使用ThreadPoolExecutor实现它,但找不到方法。可能吗 下面是一个要测试的示例 public class ExecutorExample { public static void main(String[]

我的用例:

  • 为线程池设置最小大小“N”,这意味着“N”个线程在执行器启动后始终可用
  • 为线程池设置最大大小“M”
  • 当所有“M”线程都忙时,传入任务应排队
  • 根据空闲状态的超时使(M-N)线程过期
我相信HttpClient后面的池管理器也可以进行类似的设置。我正在尝试使用ThreadPoolExecutor实现它,但找不到方法。可能吗

下面是一个要测试的示例

public class ExecutorExample {

    public static void main(String[] args) throws InterruptedException {
        int minPoolSize = 2;
        int maxPoolSize = 10;
        int ttlMillis = 100;
        ThreadPoolExecutor startupExecutor = new ThreadPoolExecutor(minPoolSize, 
                maxPoolSize, // surprisingly this is not obeyed.
                ttlMillis, 
                TimeUnit.MILLISECONDS, 
                new LinkedBlockingQueue<Runnable>());

        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + startupExecutor.getCorePoolSize());
            startupExecutor.execute(new MyRunnable(i));
        }

        for (int i = 0; i < 20; i++) {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + ":" + startupExecutor.getCorePoolSize());
        }
    }

}

class MyRunnable implements Runnable {

    int n;

    public MyRunnable(int n) {
        this.n = n;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(2000);
            System.out.println(Thread.currentThread().getName() + ":" + n);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}
公共类执行器示例{
公共静态void main(字符串[]args)引发InterruptedException{
int minPoolSize=2;
int maxPoolSize=10;
int ttlMillis=100;
ThreadPoolExecutor startupExecutor=新的ThreadPoolExecutor(最小池大小,
maxPoolSize,//令人惊讶的是,这没有得到遵守。
ttlMillis,
TimeUnit.ms,
新建LinkedBlockingQueue());
对于(int i=0;i<20;i++){
System.out.println(Thread.currentThread().getName()+”:“+startupExecutor.getCorePoolSize());
startupExecutor.execute(新MyRunnable(i));
}
对于(int i=0;i<20;i++){
睡眠(1000);
System.out.println(Thread.currentThread().getName()+”:“+startupExecutor.getCorePoolSize());
}
}
}
类MyRunnable实现Runnable{
int n;
公共MyRunnable(int n){
这个,n=n;
}
@凌驾
公开募捐{
试一试{
《睡眠》(2000年);
System.out.println(Thread.currentThread().getName()+“:”+n);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
这个怎么样:

        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);

编辑:通常我使用的队列是有界阻塞队列

BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue(queueCapacity, true);
BlockingQueue workQueue=new ArrayBlockingQueue(queueCapacity,true);
EDIT2:最大池大小仅在队列已满时生效。由于您使用的是无界队列,因此线程数不会超过2。请点击下面的链接

放上1号,你会看到区别

new LinkedBlockingQueue<>(1));
newlinkedblockingqueue(1));

编辑3:在您的示例中,使用
startupExecutor.getCorePoolSize()
更改
startupExecutor.getPoolSize()

不会
ThreadPoolExecutor(corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue)
满足您的需要?@Romanpuchkovski您心目中的队列对象是什么?我会测试的。你的要求太奇怪了。。。在传入任务排队之前,为什么需要将线程数从N增加到M?我不知道这会使线程在超时后过期。您能用您希望我使用的队列的实际实现来更新它吗?您的意思是在线程执行后使其过期吗?在超时后使空闲线程过期(显然,队列是空的,因为线程是空闲的)。我发布了一些示例代码供您测试ThreadPoolExecutor。只是运行了您的示例,有趣的是没有遵循maxPoolSize。玩弄它。