java8线程池

java线程的创建、销毁和线程减切换是一件比较耗费计算机资源的事。如果我们需要用多线程处理任务,并频繁的创建、销毁线程会造成计算机资源的无端浪费,因此出现了线程池技术。在《java并发编程的艺术》一书中,作者总结了三条使用线程池的好处:

  1. 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  2. 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
  3. 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

线程池的使用 

线程池的创建

线程池的创建可以通过创建 ThreadPoolExecutor 对象或者调用 Executors 的工厂方法来创建线程池。但是在阿里巴巴的java开发手册中提到:

【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明: Executors 返回的线程池对象的弊端如下:
1) FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
2) CachedThreadPool 和 ScheduledThreadPool:
允许的创建线程数量为 Integer.MAX_VALUE, 可能会创建大量的线程,从而导致 OOM。

ThreadPoolExecutor 

因此先看一下怎么通过创建 ThreadPoolExecutor 对象来创建一个线程池。

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) 

这是 ThreadPoolExecutor 的构造方法,其中的参数含义如下:

  • corePoolSize:核心线程池大小, 当新的任务到线程池后,线程池会创建新的线程(即使有空闲线程),直到核心线程池已满;
  • maximumPoolSize:最大线程池大小,顾名思义,线程池能创建的线程的最大数目;
  • keepAliveTime:程池的工作线程空闲后,保持存活的时间;
  • TimeUnit:时间单位;
  • BlockingQueue<Runnable>:用来储存等待执行任务的队列;
  • threadFactory:线程工厂;
  • RejectedExecutionHandler: 当队列和线程池都满了时拒绝任务的策略。

重要参数的说明:

  • corePoolSize 和 maximumPoolSize

默认情况下线程中的线程初始时为 0, 当有新的任务到来时才会创建新线程,当线程数目到达 corePoolSize 的数量时,新的任务会被缓存到 workQueue 队列中。如果不断有新的任务到来,队列也满了的话,线程池会再新建线程直到总的线程数目达到 maximumPoolSize。如果还有新的任务到来,则要根据 handler 对新的任务进行相应拒绝处理。

  • BlockingQueue<Runnable>

一个阻塞队列,用来存储等待执行的任务,常用的有如下几种:

  1. ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
  2. LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
  3. SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
  4. PriorityBlockingQueue:一个具有优先级得无限阻塞队列。
  • RejectedExecutionHandler

当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。有下面四种JDK提供的策略:

  1. AbortPolicy,表示无法处理新任务时抛出异常, 默认策略
  2. CallerRunsPolicy:用调用者所在线程来运行任务。
  3. DiscardOldestPolicy: 该策略将丢弃最老的一个请求,也就是即将被执行的任务,并尝试再次提交当前任务。
  4. DiscardPolicy:不处理,丢弃掉
  5. 除了这些JDK提供的策略外,还可以自己实现 RejectedExecutionHandler 接口定义策略。

其他用法请参考:https://blog.csdn.net/wy11933/article/details/80399562

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值