当前位置: 移动技术网 > IT编程>开发语言>Java > java~线程池的总结~续

java~线程池的总结~续

2020年03月29日  | 移动技术网IT编程  | 我要评论

主要谈了java里的线程池的使用,而主要使用executors的方式去创建,比如 executors.newcachedthreadpool(), executors.newfixedthreadpool(5)等等,而这些方式在阿里手册里是不被推荐的,而是推荐使用threadpoolexecutor的方式,我想应该也是避免资源耗尽的风险吧!

线程池不允许使用 executors 去创建,而是通过 threadpoolexecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

threadpoolexecutor实现的线程池

阿里巴巴的java开发手册推荐用threadpoolexecutor创建线程池。来看看threadpoolexecutor创建线程池的api:

public threadpoolexecutor(int corepoolsize,
                          int maximumpoolsize,
                          long keepalivetime,
                          timeunit unit,
                          blockingqueue<runnable> workqueue,
                          threadfactory threadfactory,
                          rejectedexecutionhandler handler) 

参数解释

corepoolsize : 线程池核心池的大小。
maximumpoolsize : 线程池的最大线程数。
keepalivetime : 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit : keepalivetime 的时间单位。
workqueue : 用来储存等待执行任务的队列。
threadfactory : 线程工厂。
handler  拒绝策略。

原理

有请求时,创建线程执行任务,当线程数量等于corepoolsize时,请求加入阻塞队列里,当队列满了时,接着创建线程,线程数等于maximumpoolsize。 当任务处理不过来的时候,线程池开始执行拒绝策略。

阻塞队列

arrayblockingqueue :一个由数组结构组成的有界阻塞队列。
linkedblockingqueue :一个由链表结构组成的有界阻塞队列。
priorityblockingqueue :一个支持优先级排序的无界阻塞队列。
delayqueue: 一个使用优先级队列实现的无界阻塞队列。
synchronousqueue: 一个不存储元素的阻塞队列。
linkedtransferqueue: 一个由链表结构组成的无界阻塞队列。
linkedblockingdeque: 一个由链表结构组成的双向阻塞队列。

拒绝策略

threadpoolexecutor.abortpolicy: 丢弃任务并抛出rejectedexecutionexception异常。 (默认)
threadpoolexecutor.discardpolicy:也是丢弃任务,但是不抛出异常。
threadpoolexecutor.discardoldestpolicy:丢弃队列最前面的任务,然后重新尝试执行任务。(重复此过程)
threadpoolexecutor.callerrunspolicy:由调用线程处理该任务。

executors的弊端

  1. newfixedthreadpool 和 newsinglethreadexecutor:主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 oom。
  2. newcachedthreadpool 和 newscheduledthreadpool:主要问题是线程数最大数是 integer.max_value,可能会创建数量非常多的线程,甚至 oom。

合理配置线程池大小

根据任务所需要的cpu和io资源的量可以分为:

  1. cpu密集型任务: 主要是执行计算任务,响应时间很快,cpu一直在运行,这种任务cpu的利用率很高。
  2. io密集型任务:主要是进行io操作,执行io操作的时间较长,这是cpu出于空闲状态,导致cpu的利用率不高。

为了合理最大限度的使用系统资源同时也要保证的程序的高性能,可以给cpu密集型任务和io密集型任务配置一些线程数。

  1. cpu密集型:线程个数为cpu核数。这几个线程可以并行执行,不存在线程切换到开销,提高了cpu的利用率的同时也减少了切换线程导致的性能损耗
  2. io密集型:线程个数为cpu核数的两倍。到其中的线程在io操作的时候,其他线程可以继续用cpu,提高了cpu的利用率。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网