多线程-- 十一.线程池

new Thread的弊端

    ①.每次new Thread新建对象,性能差。

    ②.线程缺乏同意管理,可能无限制的新建线程,相互竞争。有可能占用过多系统资源导致死机或OOM(程序申请内存过大)。

    ③.缺少更多功能,如更多执行,定期执行 ,线程中断。

线程池的好处

    ①.重用存在的线程,减少对象的创建和消亡的开销,性能好。

    ②.可有效控制最大并发线程数,提高系统资源利用率,同时可以避免过多资源竞争,避免阻塞。

    ③.提供定时执行,定期执行,单线程,并发数控制等功能。


一.线程池--ThreadPoolExecutor

    1.可接受的初始化参数

    ①.corePoolSize:核心线程数量

    ②.maximumPoolSize:线程最大线程数

    ③.workQueue:阻塞队列。存储等待执行的任务,很重要,会对线程池运行过程产生重大影响。

    如果运行的线程数少于corePoolSize的时候,直接创建新线程来处理任务,即使线程池中其它线程是空闲的;

    如果运行的线程数大于等于corePoolSize的时候,且小于maximumPoolSize,则只有当workQueue满了的时候,才创建新的线程来处理任务;

    如果设置的corePoolSize和maximumPoolSize相同,那么创建的线程池大小是固定的。这个时候如果有新任务提交,并且workQueue没满的时候,就把请求放入到workQueue里面,等待有空闲的线程,从里面取出进行处理;

    如果我们运行的线程数量大于maximumPoolSize,workQueue也已经满了的时候,那么通过拒绝策略参数来处理。

    ④.keepAliveTime:线程没有任务执行时最多保持多久时间终止。

    ⑤.unit:keepAliveTime的时间单位。

    ⑥.threadFactory:线程工厂,用来创建线程。

    ⑦.rejectHandle:当拒绝处理任务时的策略。

    如果workQueue满了并且没有空闲线程时,这时候如果还在提交任务,就需要策略来处理。

    常用的策略:

        默认策略是直接抛异常;

        丢弃掉阻塞队列中最靠前的任务;

        用调用者所在线程来执行任务;

        直接丢弃当前任务;

        

2.线程池的几种状态

    

    RUNNING:接受新提交的任务,也能处理阻塞队列里的任务。

    SHUTDOWN:关闭状态。当处于SHUTDOWN状态时,不能接收新提交的任务,但是可以继续处理阻塞队列中已经保存的任务。在线程池处于 RUNNING状态时,调用shutdown()方法会使线程进入该状态。

    STOP:不能接收新提交的任务,也不可以继续处理阻塞队列中已经保存的任务。会中断正在处理任务的线程。调用shutDownNow()方法时,会进入该状态。

    TIDYING:如果所有任务都终止,线程池中工作线程数量为0,会进入该状态。

    TERMINATED:之后调用terminated()方法,会进入TERMINATED状态。

3.提供的一些方法

    ①.execute():提交任务,交给线程池执行。

    ②.submit():提交任务,能够返回执行结果。相当于execute+Future

    ③.shutdown():关闭线程池,前提是等待任务都执行完。

    ④.shutdownNow():关闭线程池,不等待任务都执行完。

    ⑤.getTaskCount():线程池已执行和未执行的任务总数。

    ⑥.getCompletedTaskCount():线程池已完成的任务数量。

    ⑦.getPoolSize():线程池当前的线程数量。

    ⑧.getActiveCount():当前线程池中正在执行任务的线程数量。

二.线程池--线程池类图

    JUC里面有3个Excutor接口,分别是Executor,ExecutorService,ScheduledExecutorService

    Executor:运行新任务的简单接口。

    ExecutorService:扩展了Executor,添加了一些用来管理生命周期的方法。

    ScheduledExecutorService:扩展了ExecutorService,支持Future和定期执行。

三.线程池--Excutor框架接口

    1.Executors.newCachedThreadPool():创建一个可缓存的线程池。可以灵活回收。

    2.Executors.newFixedThreadPool():创建一个定长的线程池。

    3.Executors.newScheduledThreadPool():创建一个定长的线程池。支持定时,周期性任务执行。

    4.Executors.newSingleThreadExecutor():创建一个单线程化的线程池。只会用唯一的线程来执行任务。

四.线程池--线程池配置

    1.CPU密集型任务,就需要尽量压榨CPU,参考值可以设为NCPU+1。

    2.IO密集型任务,参考值可以设置为2*NCPU

猜你喜欢

转载自blog.csdn.net/zhmystic/article/details/82117705