JDK并发包中的线程池(二)核心线程池的内部实现
来源:互联网 发布:selenium java client 编辑:程序博客网 时间:2024/06/11 11:52
对于核心的几个线程池
newSingleThreadExecutornewFixedThreadPoolnewCachedThreadPool
其内部都是使用的ThreadPoolExecutor实现的,下面给出它们的实现方式:
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());}public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));}public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());}
我们再来看看ThreadPoolExecutor的构造方法
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {}
参数说明:
corePoolSize:线程池中线程的数量
maximumPoolSize:线程池中最大的线程的数量
keepAliveTime:当线程池中线程的数量超过maximumPoolSize时,多余的空闲的线程的存活时间
unit:keepAliveTime的单位
workQueue:任务队列,存放已经提交但尚未被执行的任务
threadFactory:产生现成的工厂
handler:当任务太多来不及执行的时候的拒绝策略
重点介绍workQueue,它是一个BlockingQueue的接口的对象,根据队列的功能分类,可以使用下面几种BlockingQueue的实现:
1. SynchronousQueue,其没有容量,没进行一次put都必须等待一个相应的take,反之亦然,提交的任务不会被真实的保存,而总是将新任务提交给线程执行,如果没有空闲的线程并且线程数量还没有达到maximumPoolSize,则尝试创建新的线程,如果已经达到最大的线程数,那么就会执行拒绝策略
2. ArrayBlockingQueue,ArrayBlockingQueue必须包含一个参数,用于表示该队列的最大的容量,如果线程池的数量小于corePoolSize,那么提交任务后就会创建新的线程用于执行任务,如果线程池的数量大于corePoolSize,那么就会将任务假如等待队列ArrayBlockingQueue中,如果队列满了的话,线程池中线程的数量也没有达到maximumPoolSize,那么会创建新的线程执行任务,若大于了maxmium,那么就会执行拒绝策略。由此可见,ArrayBlockingQueue只有在队列满了的情况下,线程池中的线程数量才会突破corePoolSize个。
3. LinkedBlockingQueue,与有界队列ArrayBlockingQueue不一样的,除非系统资源耗尽,否则无界队列不存在任务入队失败的情况,当有新的任务进来的时候,如果线程池中线程的数量不足corePoolSize,那么会创建新的线程执行任务,但是当线程池中的线程的数量达到corePoolSize的时候,则任务就会直接进入到LinkedBlockingQueue中
在此,我们就不难发现为什么newFixedThreadPool实现的时候使用的是LinkedBlockingQueue,而newCachedThreadPool实现的时候使用的是SynchronousQueue。
拒绝策略
JDK内置的拒绝策略如下:
AbortPolicy:直接抛出异常
CallerRunsPolicy:直接在调用者的线程中,运行当前被丢弃的任务
DiscardOledestPolicy:丢弃掉最老的一个任务
DiscardPolicy:默默地丢弃无法处理的任务,不予任何处理
拒绝策略的源代码如下所示:
public static class AbortPolicy implements RejectedExecutionHandler { public AbortPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); }}public static class CallerRunsPolicy implements RejectedExecutionHandler { public CallerRunsPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } }}public static class DiscardOldestPolicy implements RejectedExecutionHandler { public DiscardOldestPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { e.getQueue().poll(); e.execute(r); } }}public static class DiscardPolicy implements RejectedExecutionHandler { public DiscardPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { }}
- JDK并发包中的线程池(二)核心线程池的内部实现
- JDK并发包中的线程池(一)
- JDK并发包线程池(三)自定义线程池
- jdk线程池的核心代码
- 线程池的核心实现
- jdk5.0并发包线程池的实现机制
- jdk5.0并发包线程池的实现机制
- JDK线程池的实现
- JDK中的线程池
- 并发编程--线程池ThreadPoolExecutor实现原理(二)
- java线程池并发包
- Java线程总结(五):并发包------线程池Executors
- Java 1.5并发包之二:任务与线程池
- 并发包-Semaphore实现线程的通信
- 线程并发库<二>_线程池
- java并发(二十)线程池
- Java并发编程(二)--线程池
- Java 并发编程之线程池的使用 (二)
- 【深度学习】GANs与DCGAN
- Maven入门介绍
- OPENSSL 制作 Ikev2证书
- 内存管理-防止泄露
- 逻辑回归与梯度下降
- JDK并发包中的线程池(二)核心线程池的内部实现
- java多线程通信
- 2017 计蒜之道 复赛 腾讯消消乐
- Spatial Transformer Networks
- spring bean 标签的解析和注册
- windows-exploit-suggester.py
- DNS在什么时候使用TCP,在什么时候使用UDP
- HTML基础学习-7- 列表学习3
- ESP8266浏览器发送数据到远程设备测试OK