线程池初探

36 篇文章 0 订阅

1. 线程池存在的问题

1.提交到线程池的任务避免依赖于其他的任务,否则对线程池的执行策略带来了约束,出现活跃度的问题
2.对于时间敏感的操作,比如GUI应用,将一个长时间运行的任务提交到单线程话的Exuctor中,或者将多个长时间运行的任务提交到只包含少量线程的线程池中或削弱Executor管理的服务的响应性
3.不应该在线程池中使用ThreadLocal变量

当线程池都是同类的,独立的时候线程池才会有最佳的工作表现。如果将耗时的与短时的混合在一起,除非线程池很大,否则会有阻塞的风险,如果提交的任务依赖于其它的任务,除非池是无限的否则有死锁的可能性

1.1线程饥饿死锁问题

在单线程话的线程池中,如果一个正在运行的线程需要等待等待队列中的线程那么会造成死锁
除了显示的限制也存在隐式的限制,比如资源的限制,比如一个只包含10个连接的jdbc线程池,每个任务需要一个数据库连接,那么一个线程池中最多只能有10个线程在运行,其它线程在等待

1.2等待,耗时操作问题

如果任务需要过长的任务时间,这可能会使当前线程池所有线程都出现响应性问题
耗时操作的解决方案:
限定等待任务等待资源的时间,而不是无限制的等待下去,如果等待超时,可以把当前任务表示为失败,终止它或者重新放回到队列中

定制线程池的大小

线程池的大小取决于未来提交的任务类型和所部署系统的特性。
很少会有人把线程池的长度硬编码,池的长度应该有某种配置机制来提供,或者利用Runtime.availableProcessors的结果,动态的计算。定制线程池大小避免过大或者过小

获取处理器个数
Runtime.getRuntime().availableProcessors()

对于计算密集型的任务:
线程池的大小应该是n+1个线程(n是CPU数目)
对于IO等阻塞任务
通常对这种任务需要更大的线程池,为了正确设置线程池的长度必须估算任务花在等待时间和用来计算时间的比率
线程数量=cpu数量目标cpu的使用效率(1+等待时间与计算时间比率)

2.配置ThreadPoolExecutor

ThreadPoolExecutor为Executor提供了基本的实现,这些Executors工厂的newCachedThreadPool、newFixedThreadPool和newScheduledThreadExecutor返回

线程池的大小,最大池的大小和存活时间共同管理线程的创建与销毁
即使没有任务执行,池的大小也等于核心池的大小直到工作队列充满前池都不会创建新的线程,最大池的大小是可同时活动的线程数的上限。如果一个线程已经闲置的时间超过了存活的时间,它会成为一个被回收的候选者,如果当前池的大小超过了核心池的大小,线程池会终止它

newFixedThreadPool工厂为请求的池设置了核心池的大小和最大池的大小,而且池永远不会超时,newCachedThreadPool将最大池的大小设置为Integer.MAX_VALUE,核心池大小设置为0,超时设置为一分钟,这样的线程池时可以无限扩大的线程池,会在需求量减少的情况下减少线程的数量

allowCoreThreadTimeOut允许所有的池线程响应超时

管理队列任务

如果新请求超过了线程池最大线程数,那么请求会在队列中等待,在队列数目过多时,请求的等待时间会增加
newFixedThreadPool和newSingleThreadExecutor默认使用的是一个无限的LinkedBlockingQueue。但是我们应该使用有界队列以避免资源耗尽的问题。对于一个有界队列,队列的长度与池的长度必须一起调节。一个大队列加一个小池,可以控制内存和CPU的使用,减少上下文切换,但要接受潜在的吞吐量开销。
对于庞大或者无界的池可以使用SynchronousQueue,完全绕开队列,将任务直接从生产者移交到工作者线程,SynchronousQueue不是一个真正的队列,而是一种管理直接在线程间移交信息的机制,为了把一个元素放入到SynchronousQueue中,必须有另一个线程正在等待接受移交的任务,如果没有这样的线程,只要池的大小还小于最大值,池会创建一个新的线程。否则提交会被拒绝。newCachedThreadPool就是用了这个SynchronousQueue

饱和策略

  1. AbortPolicy:直接抛出异常
  2. CallerRunsPolicy:用调用者所在的线程执行
  3. DiscardOldestPolicy:丢弃队列中最近的一个task
  4. DiscardPolicy:不处理,直接丢弃
  5. 根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值