在写这篇文章前,我在网上查了很多介绍这方面的文章,现在打算自己总结一下。
jdk文档中说:TheadPoolExecutor是Executors类的底层实现。
那么也就是说Executors更好用一些。那么看一下它都有哪些用法。
=================================================================
Executors.newCacheThreadPool() 这个是线程池是无界的,可以自动进行线程回收。
Executors.newFixedThreadPool(int)这个可以设置固定大小
Executors.newSingleThreadExecutor()单个后台线程。
以拿 Executors.newFixedThreadPool(int)这例,它的实现背后是
public static ExecutorService newFixedThreadPool(int threadNum){
return new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue
)}
其中最后一个参数BlockingQueue<Runnable> workQueue,它其实可以这样理解
在进入到线程池之前需要进行排队,也就是说:如果当前线程池中有空闲线程的话,则直接把任务给空闲线程。
如果没有空闲位置的话,则需要进行排队。
那么排除也有三种方式:
第一种(默认)SynchronousQueue 直接把任务给空闲线程,如果没有空闲的话,把最新的线程放到队列里,队列里只允许有一个任务(这是SynchronousQueue特性),如果再有任务,则线程池创建新的线程。但如果创建的线程数超过max值的时候,任务就会被拒绝。为避免这种情况在使用SynchronousQueue通常要求maximumPoolSize是无界的。这种方式作用:可以避免在处理可能具有内部依赖性的请求集时出现锁。举例说明:如果你的任务A1,A2有内部关联,A1需要先运行,那么先提交A1,再提交A2,当使用SynchronousQueue我们可以保证,A1必定先被执行,在A1么有被执行前,A2不可能添加入queue中。
注意:线程池里的线程是核心线程,与新建线程是有区别的。
第二种 LinkedBlockingQueue (无界队列)如果线程池中没有空闲线程的话,则任务就在队列中排除等待。这样的话,创建的线程数量就不会超过corePoolSize设置的参数了。所以maxmumPoolSize 的值就无效了。
第三种 ArrayBlockingQueue(有界对列)CPU使用率较高。防止资源耗。但JDK并不推荐使用,太复杂了。
=================================================================