线程池

线程池创建的七种方式

|____________________________________________________________________________________________________
|	I Executor                                                                                       |
|		/						                                                                     |
|I ExcutorService、I ScheduledExecutorService                                                        |
|		|                                                                                            |
|		|						                                                                     |
|		AbstractExecutorService                                                                      |
|		\                                                                                            |
|		1.ThreadPoolExecutor  (最原始的线程池创建方式,2~4 是基于1的封装)                          |
|----------------------------------------------------------------------------------------------------|
|	Executors                                                                                        |
|	|--2.newSingleThreadExecutor()        //创建单线程池	                                         |
|	|--3.newCachedThreadPool()            //适用大量短时任务,池子可伸缩,工作队列为SynchronousQueue |
|	|--4.newFixedThreadPool(int nThreads) //创建n线程池                                              |
|	|                                                                                                |
|	|--5.newSingleThreadScheduledExecutor()      //创建单线程池,可以进行定时或周期性的工作调度      |
|	|--6.newScheduledThreadPool(int corePoolSize)//创建n线程池,可以进行定时或周期性的工作调度       |
|	|                                                                                                |
|	|--7.newWorkStealingPool(int parallelism)//jdk8 引入                                             |
|____________________________________________________________________________________________________|

ThreadPoolExecutor(核心类)

/**
 *ThreadPoolExecutor|--核心线程数
 *					|--最大线程数
 *					|--存活时间
 *					|--时间单位
 *					|--工作队列(阻塞队列)
 */
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, 
		 maximumPoolSize, 
		 keepAliveTime, 
		 unit, 
		 workQueue,
		 Executors.defaultThreadFactory(), 
		 defaultHandler);
}

BlockingQueue(常用工作队列)

|
|--1.ArrayBlockingQueue      //内部基于数组来存放元素,一个典型的“固定有界缓存区”,一旦创建,就不能再增加其容量。
|--2.DelayBlockingQueue _/\  //一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能到期时才能从队列中取走
|--3.LinkedBlockingQueue   | //内部基于链表来存放元素,如果不指定容量,默认为Integer.MAX_VALUE,也就是无界队列
|--4.PriorityBlockingQueue | //保证每次取出的元素都是队列中权值最小的,即通过完全二叉树实现的小顶堆
|--5.SynchronousQueue      | //它内部没有容器,来一个任务则创建一个线程,池子无法承受时会拒绝任务
						   |
		                   PriorityQueue
						   
阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止。
                 同样,当队列为空时候,请求队列元素的操作同样会阻塞等待,直到有可用元素为止。

public class DelayQueue<E extends Delayed> extends AbstractQueue<E> implements BlockingQueue<E>
DelayQueue阻塞队列在我们系统开发中也常常会用到,底层使用的是PriorityQueue
例如:缓存系统的设计,缓存中的对象,超过了空闲时间,需要从缓存中移出;
	  任务调度系统,能够准确的把握任务的执行时间。
	  
SynchronousQueue 也是一个队列来的,但它的特别之处在于它内部没有容器,一个生产线程,当它生产产品(即put的时候),
如果当前没有人想要消费产品(即当前没有线程执行take),此生产线程必须阻塞,等待一个消费线程调用take操作,
take操作将会唤醒该生产线程,同时消费线程会获取生产线程的产品(即数据传递)

submit 和 execute的区别

1submit()方法中参数可以是Callable类型也可以是Runnable类型,而execute()方法参数只能是Runnable类型。
2、submit有返回值,而execute没有
用到返回值的例子,比如说我有很多个做validation的task,我希望所有的task执行完,然后每个task告诉我它的执行结果,是成功还是失败,
如果是失败,原因是什么。然后我就可以把所有失败的原因综合起来发给调用者。cancel execution这个用处不大,很少有需要去取消执行的。
3、Callable 类型的任务可以获取执行的返回值,而 Runnable 执行无返回值;submit方便Exception处理;
意思就是如果你在你的task里会抛出checked或者unchecked exception,
而你又希望外面的调用者能够感知这些exception并做出及时的处理,那么就需要用到submit,通过捕获Future.get抛出的异常。

|-----------------------------------------------------------------------|
|    public Future<?> submit(Runnable task) {                           |
|        if (task == null) throw new NullPointerException();            |
|        RunnableFuture<Void> ftask = newTaskFor(task, null);           |
|        execute(ftask);                                                |
|        return ftask;                                                  |
|    }                                                                  |
|-----------------------------------------------------------------------|	
|	  public <T> Future<T> submit(Runnable task, T result) {            |
|        if (task == null) throw new NullPointerException();            |
|        RunnableFuture<T> ftask = newTaskFor(task, result);            |
|        execute(ftask);                                                |
|        return ftask;                                                  |
|    }                                                                  |
|-----------------------------------------------------------------------|
|    public <T> Future<T> submit(Callable<T> task) {                    |
|        if (task == null) throw new NullPointerException();            |
|        RunnableFuture<T> ftask = newTaskFor(task);                    |
|        execute(ftask);                                                |
|        return ftask;                                                  |
|    }                                                                  |
|-----------------------------------------------------------------------|

RejectedExecutionHandler(线程池拒绝策略:调用具体handler的rejectedExecution方法)

|
|-前置条件:当一个任务通过execute(Runnable)方法欲添加到线程池时
|          |
|          |--l.如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
|          |   
|          |--2.如果此时线程池中的数量等于corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
|          |   
|          |--3.如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
|          |   
|          |--4.如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
|          |    也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。  
|          
|-四种拒绝策略|--1.RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();//这个是默认策略
|             |--  此策略  :将抛出 RejectedExecutionException.
|             |--  源码如下:public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
|             |                 throw new RejectedExecutionException("Task "
|             |             	                                     + r.toString()
|             |             										 +" rejected from"
|             |             										 +e.toString());
|             |             }
|             |
|             |--2.RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
|             |--  此策略  :用于被拒绝任务的处理程序,它直接执行被拒绝的任务;如果线程池已关闭,则会丢弃该任务。
|             |--  源码如下:public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
|             |                 if (!e.isShutdown()) {
|             |                     r.run();
|             |                 }
|             |             }
|             |
|             |--3.RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
|             |-- 此策略  :首先丢掉缓存在队列中的最早的任务,然后重新尝试运行该任务。
|             |-- 源码如下:public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
|             |                if (!e.isShutdown()) {
|             |                    e.getQueue().poll();
|             |                    e.execute(r);
|             |                }
|             |            }
|             |
|             |--4.RejectedExecutionHandler handler = ThreadPoolExecutor.DiscardPolicy();
|             |--  此策略  :什么也不做,之间丢弃;
|             |--  源码如下: /**
|             |              * Does nothing, which has the effect of discarding task r.
|             |              * @param r the runnable task requested to be executed
|             |              * @param e the executor attempting to execute this task
|             |              */
|             |             public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
|             |             }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值