java线程池:ThreadPoolExecutor类

线程池:ThreadPoolExecutor类

最重要构造方法:

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

    新来一个任务时候:
        如果当前运行线程数量小于corePoolSize,则线程池会直接创建线程来执行任务,即使此时线程池中存在空闲线程;
        如果当前运行线程数量>=corePoolSize,
            a.如果任务队列有空余位置,则将任务加入队列
            b.如果任务队列没有空余位置,
                1)如果当前运行线程数量<maxPoolSize,则直接创建一个线程运行该任务
                2) 根据拒绝策略处理该任务
corePoolSize 指核心线程数大小,一般情况下,线程池中的线程数不会超过此值

maxPoolSize  指线程池能允许的最大线程数大小。当任务提交过快,需要提高处理速率的时候,
                    线程池会生成更多的线程,此时线程数可能会超过corePoolSize,但不会超过maxPoolSize

keepAliveTime 如果当前线程数超过了corePoolSize,但是存在一些空闲的线程的话,这些空闲线程存活时间不会超过这个值

unit 配合keepAliveTime使用

workQueue 任务缓存队列

threadFactory 线程工程,用来创建线程

handler  任务拒绝提交策略

线程池状态

ThreadPoolExecutor有以下两种关闭方法:

void shutdown()
void shutdownNow()

配合这两种关闭方法,有4中线程池状态:RUNNING,SHUTDOWN,STOP,TERMINATED

当创建一个线程池的时候,线程池处于RUNNING状态;
当调用shutdown()方法时,线程池处于SHUTDOWN状态,此时线程池不接受新的任务,但会等待所有任务执行完毕;
当调用shutdownNow()方法时,线程池处于STOP状态,此时线程池不接受新的任务,并且会尝试终止正在执行的任务;
当线程池处于SHUTDOWN或者STOP状态,且所有的工作线程都已经被销毁,任务缓存队列清空之后,线程池处于TERMINATED状态。

任务提交和执行的过程

当线程池状态处于RUNNING时,提交一个任务:
    有界的任务提交:使用ArrayBlockingQueue实现(指定其大小)
    1.如果当前线程池中线程数量 <corePoolSize 的话,则直接创建一个线程去执行这个任务
    2.如果当前线程数 >=corePoolSize 的话,
        a. 如果任务缓存队列有空位,则将该任务放入队列,等待线程执行
        b. 如果任务缓存队列已经满了:
            a) 如果当前线程数 <maxPoolSize ,则直接创建一个新的线程去执行这个任务
            b) 若果当前线程数 >=maxPoolSize, 则采取拒绝策略,不允许加入任务

    无界的任务提交:使用LinkedBlockingQueue实现
    1.如果当前线程池中线程数量 <corePoolSize 的话,则直接创建一个线程去执行这个任务
    2.如果当前线程数 >=corePoolSize 的话,将任务加入缓存队列

    直接提交队列:使用SynchronousQueue实现
    1.如果当前线程池中线程数量 <corePoolSize 的话,则直接创建一个线程去执行这个任务
    2.如果当前线程数 >=corePoolSize 的话,
        a. 如果当前线程数 <maxPoolSize ,则直接创建一个新的线程去执行这个任务
        b. 若果当前线程数 >=maxPoolSize, 则采取拒绝策略,不允许加入任务

    优先级任务队列:使用PriorityBlockingQueue实现
    是一个特殊的无界任务队列,在无界任务队列的基础上考虑了任务的优先级。(前三队列是先进先出,而该队列根据优先级来调度任务)

在线程数 >corePoolSize,且 <=maxPoolSize的时候,选定一个空闲线程,如果该空闲线程的空闲时间超过keepAliveTime(配合TimeUnit)的话,该线程会被终止。知道线程数量不超过corePoolSize

利用工程方法创建线程池

Executors中有静态方法:

public static ExecutorService newFixedThreadPool(int nThreads)
        此时,corePoolSize=maxPoolSize=nThreads,使用LinkedBlockigQueue。
        当提交任务很频繁,而任务又比较耗时的话,队列会快速膨胀,容易耗尽系统资源

public static ExecutorService newSingleThreadExecutor()
        此时,corePoolSize=maxPoolSize=1,使用LinkedBlockigQueue。
        是newFixedThreadPool(1)的简写

public static ExecutorService newCachedThreadPool()
        此时,corePoolSize=0,maxPoolSize=无穷大,使用SynchronousQueue。
        提交任务时,有空闲线程的话就使用空闲线程,没有就创建新线程。
        当提交任务很频繁,而任务又比较耗时的话,会创建大量的线程,容易耗尽系统资源

public static ScheduledExecutorService newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)



注:ThreadPoolExecutor类和ScheduledExecutorService都继承了ExecutorService

拒绝策略

向线程池添加任务,如果该任务不能向线程池中添加的话,会执行拒绝策略。
四种拒绝策略如下:

AbortPolicy:直接抛出异常
CallerRunsPolicy:如果线程池没有被关闭,则在调用线程中,执行该被丢弃的任务。注意,这会影响调用线程的性能
DiscardOledestPolicy:丢弃最老的一个任务(即将被执行的那个任务),然后尝试再次提交
DiscardPolicy:不做任何处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值