Java ThreadPoolExecutor与Executors.cachedThreadPool类似,但具有最大线程数和队列

Java ThreadPoolExecutor与Executors.cachedThreadPool类似,但具有最大线程数和队列,java,multithreading,asynchronous,concurrency,java.util.concurrent,Java,Multithreading,Asynchronous,Concurrency,Java.util.concurrent,这是缓存的线程池: new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); newthreadpoolexecutor(0,Integer.MAX_值,60L,TimeUnit.SECONDS,new SynchronousQueue()); 这是固定线程池执行器: new ThreadPoolExecutor( 0, 20, 60

这是缓存的线程池:

new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
newthreadpoolexecutor(0,Integer.MAX_值,60L,TimeUnit.SECONDS,new SynchronousQueue());
这是固定线程池执行器:

new ThreadPoolExecutor( 0, 20, 60L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
newthreadpoolexecutor(0,20,60L,TimeUnit.ms,newlinkedblockingqueue());
第一个可以创建INTEGER.MAX_值线程数,这在我的例子中是不需要的

第二个是不正确的。对于LinkedBlockingQueue,不能使用最少0个线程,最多20个线程

从文件中:

使用无界队列(例如,不带 预定义容量)将导致新任务在 所有corePoolSize线程都很忙。因此,不超过corePoolSize 将永远创建线程。(以及maximumPoolSize的值 因此没有任何效果。)

使用SynchronousQueue在第一种情况下,CachedThreadPool实际上没有队列的作用。它只会根据需要创建线程,并且需要较高的上限

工作队列的一个好的默认选择是 将任务交给线程,而不以其他方式控制它们。这里,一个 如果没有立即启动线程,则尝试将任务排队将失败 可以运行它,因此将构造一个新线程。这项政策 在处理可能具有内部权限的请求集时避免锁定 依赖关系。直接切换通常要求无限制切换 最大化工具大小以避免拒绝新提交的任务。这个 turn允许在执行命令时出现无限线程增长的可能性 继续以平均比处理速度更快的速度到达

现在,我想要的是:

我想要的是一个可以提交工作的执行器,如果maxThreads都很忙,它会使用一个队列,但这也允许线程空闲,并且在没有工作时不会占用任何资源

使用:

ThreadPoolExecutor ex = new ThreadPoolExecutor(0, threads, 60L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
ex.setKeepAliveTime(idletime, TimeUnit.MILLISECONDS);
ThreadPoolExecutor ex=new ThreadPoolExecutor(0,threads,60L,TimeUnit.ms,new LinkedBlockingQueue());
例如,setKeepAliveTime(空闲时间,时间单位为毫秒);
我不知道这意味着什么。文档似乎只解释了无界LinkedBlockingQueue的使用,我不确定这意味着什么,因为构造函数创建了一个最大容量为Integer.max_值的队列

文件还指出:

(因此,maximumPoolSize的值没有任何 效果。)

我想要的是一个最小线程池大小和一个最大线程池大小,用于排队等待工作,并在没有工作时让线程空闲。

编辑

阅读这个问题,最后一部分让我考虑是否应该创建一个

新的ThreadPoolExecutor(20,?无关?,60L,时间单位为毫秒,新 LinkedBlockingQueue())

这将创建20个线程,如果

例如,setKeepAliveTime(60L,时间单位为毫秒)

一切就绪

这是正确的假设吗

我想要的是一个最小的线程池大小和一个最大的线程池大小,当没有工作时,它可以排队工作并让线程空闲

这正是具有无限队列的固定线程池所能提供的。简而言之,定义一个线程池,如

new ThreadPoolExecutor( 0, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
newthreadpoolexecutor(0,20,0L,TimeUnit.ms,newlinkedblockingqueue());
这就是你所需要的。您得到的是一个最多有20个线程的线程池,以及一个可以接受“无限”数量任务的工作队列

那么,如果队列是空的呢?线程池将使20个线程仍处于活动状态并在队列中等待。当线程在队列上等待时,它们将挂起并且不工作

我要做的一个更新是将
0L,TimeUnit.ms
更改为稍高一点的值,如
1L,TimeUnit.SECONDS
。这是线程空闲期,在关闭线程之前,应该让线程保持一段时间的活动状态

简言之,线程池实现了我认为您需要的功能。如果是这样,请在评论中告诉我,我可能遗漏了一些东西

我想要的是一个最小的线程池大小和一个最大的线程池大小,当没有工作时,它可以排队工作并让线程空闲

这正是具有无限队列的固定线程池所能提供的。简而言之,定义一个线程池,如

new ThreadPoolExecutor( 0, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
newthreadpoolexecutor(0,20,0L,TimeUnit.ms,newlinkedblockingqueue());
这就是你所需要的。您得到的是一个最多有20个线程的线程池,以及一个可以接受“无限”数量任务的工作队列

那么,如果队列是空的呢?线程池将使20个线程仍处于活动状态并在队列中等待。当线程在队列上等待时,它们将挂起并且不工作

我要做的一个更新是将
0L,TimeUnit.ms
更改为稍高一点的值,如
1L,TimeUnit.SECONDS
。这是线程空闲期,在关闭线程之前,应该让线程保持一段时间的活动状态


简言之,线程池实现了我认为您需要的功能。如果是这样的话,我可能会遗漏一些东西。请在评论中告诉我。

这可能有帮助:(如何让ThreadPoolExecutor在排队前将线程增加到最大值?

这可能有帮助:(如何让ThreadPoolExecutor在排队前将线程增加到最大值?

fixedThreadPool()的文档)声明:池中的线程将一直存在,直到它显式地被ExecutorService.shutdown()执行。这是否意味着他们正在占用资源,倾听工作?请参阅我对我的问题所做的编辑。
这是否意味着他们正在占用资源、倾听工作
?不,他们不是,一个等待的区域