深入理解线程池

Java 新民 562℃ 已收录 3评论

一、线程池的概述:

在多线程操作中,为了避免多线程操作造成的系统开销问题,  在JDK 1.5 之后新添加了线程池。

二、 线程池的使用

在java.util.concurrent 包中, 有个Executors 类,为我们封装了各种线程池的创建。 从而简化了线程池的创建和使用。我们只需要Executors.newXXXThreadPool(…) ,就可以成功的创建一个线程池。但是我们都知道,在线程池中使用队列,在Java中为我们提供了两种队列: 阻塞队列非阻塞队列。 在通常情况下阻塞队列有界的,非阻塞队列无界的。非阻塞队列在某些场景下性能优于阻塞队列。那么问题来了,非阻塞队列性能虽优于阻塞队列,但是在高并发场景下,也会导致OOM问题。所以在使用Executors类创建线程池时,有可能会导致OOM问题。下面来给出线程池正确的创建方式:

	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
													5 ,
													0, 
													TimeUnit.SECONDS, 
													new ArrayBlockingQueue<>(512)  // 使用有界队列,防止OOM发生
												);

三、线程池的任务拒绝策略

线程池的拒绝策略主要是RejectExecutionHandler来做对应拒绝策略。 下面来看看,这个拒绝策略的类图:

上面提供了4个实现类。 我们来介绍下,这些实现类的拒绝行为:

1、AbortPolicy : 该类拒绝是抛出RejectedExecutionException

2、CallerRunsPolicy: 直接由提交任务者执行该任务

3、DiscardOldestPolicy: 丢弃执行队列中最老的任务,尝试为当前提交的任务腾出位置

4、DiscardPolicy: 直接忽略

在线程池中默认的拒绝行为是 AbortPolicy , 直接抛出RejectedExecutionException。该异常是非受检异常,如果不关心任务被拒绝,可以将拒绝行为设置为 DiscardPolicy。 下面给了代码例:

	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
				5 ,
				0, 
				TimeUnit.SECONDS, 
				new ArrayBlockingQueue<>(512),  // 使用有界队列,防止OOM发生
				new ThreadPoolExecutor.AbortPolicy()
			);

四、线程池的正确构造

	RejectedExecutionHandler executionHandler = new ThreadPoolExecutor.DiscardPolicy();
		int availableProcessors = Runtime.getRuntime().availableProcessors() * 2;
		BlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(512);
		ThreadPoolExecutor threadPoolExecutor2 = new ThreadPoolExecutor(
				availableProcessors,
				availableProcessors, 
				0, 
				TimeUnit.SECONDS, 
				arrayBlockingQueue, executionHandler);
本站文章如未注明,均为原创丨本网站采用BY-NC-SA协议进行授权,转载请注明转自:https://www.snowruin.com/?p=1755
喜欢 (2)or分享 (0)
发表我的评论
取消评论
表情 代码 贴图 加粗 链接 私信 删除线 签到

Hi,请填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(3)条精彩评论。
  1. 认真学习一下
    跨境电商导航2018-12-21 19:40 回复| Firefox 47.0| unknow
  2. 交换链接吗
    Godaddy优惠码2018-12-19 08:28 回复| Google Chrome 63.0.3239.132| Windows 8.1 x64
  3. 感谢分享,虽然我还没有理解(手动捂脸) 😛
    楚狂人博客2018-12-16 17:07 回复| Google Chrome 63.0.3239.132| unknow