一、java线程池的参数
1. corePoolSize:指定了线程池中的线程数量。 次时间内会被销毁。 4. unit:keepAliveTime 的单位。 7. handler:拒绝策略,当任务太多来不及处理,如何拒绝任务。 |
|
二、默认线程工厂
DefaultThreadFactory() { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; }
三、拒绝策略
线程池中的线程已经用完了,无法继续为新任务服务,同时,等待队列也已经排满了,再也 塞不下新任务了。这时候我们就需要拒绝策略机制合理的处理这个问题。
JDK 内置的拒绝策略如下:
1. AbortPolicy : 直接抛出异常,阻止系统正常运行。
2. CallerRunsPolicy : 只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的 任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。
3. DiscardOldestPolicy : 丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再 次提交当前任务。
4. DiscardPolicy : 该策略默默地丢弃无法处理的任务,不予任何处理。如果允许任务丢 失,这是最好的一种方案。
以上内置拒绝策略均实现了 RejectedExecutionHandler 接口,若以上策略仍无法满足实际
需要,完全可以自己扩展 RejectedExecutionHandler 接口。
默认拒绝策略为AbortPolicy。
四、阻塞队列
ArrayBlockingQueue :由数组结构组成的有界阻塞队列。支持公平锁和非公平锁两种ReenTrantLock
LinkedBlockingQueue :由链表结构组成的有界阻塞队列。向队列中放值和从队列中取值使用的事两个ReentrantLock,所以会提升效率。
PriorityBlockingQueue :支持优先级排序的无界阻塞队列。利用的节点方式,可以使用优先级,也可以不使用,使用的时候是遍历所有的节点进行比较。
DelayQueue:使用优先级队列实现的无界阻塞队列。该队列可以设置延时,延迟时间未过不允许取该数据。
SynchronousQueue:不存储元素的阻塞队列。是一个不存储元素的阻塞队列。每一个 put 操作必须等待一个 take 操作,否则不能继续添加元素,实际上该队列并没有储存多个元素。
LinkedTransferQueue:由链表结构组成的无界阻塞队列。
transfer 方法:如果当前有消费者正在等待接收元素(消费者使用 take()方法或带时间限制的
poll()方法时),transfer 方法可以把生产者传入的元素立刻 transfer(传输)给消费者。如
果没有消费者在等待接收元素,transfer 方法会将元素存放在队列的 tail 节点,并等到该元素
被消费者消费了才返回。
tryTransfer 方法。则是用来试探下生产者传入的元素是否能直接传给消费者。如果没有消费
者等待接收元素,则返回 false。和 transfer 方法的区别是 tryTransfer 方法无论消费者是否
接收,方法立即返回。而 transfer 方法是必须等到消费者消费了才返回。
LinkedBlockingDeque:由链表结构组成的双向阻塞队列
是一个由链表结构组成的双向阻塞队列。所谓双向队列指的你可以从队列的两端插入和移出元素。
双端队列因为多了一个操作队列的入口,在多线程同时入队时,也就减少了一半的竞争
二、常用线程池
newCachedThreadPool() new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>()); newFixedThreadPool() new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()); newSingleThreadExecutor() new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>())); newScheduledThreadPool() public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); } newSingleThreadScheduledExecutor() new ScheduledThreadPoolExecutor(1)