ThreadPoolExecutor 分析

自定义的ThreadPoolExecutor, 代码如下:

public void init() {

    this.service = new ThreadPoolExecutor(30, 200, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),

                                          new CustomizableThreadFactory("ruleExecute"));

}

ThreadPoolExecutor的构造函数

public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,

                          long keepAliveTime,

                          TimeUnit unit,

                          BlockingQueue<Runnable> workQueue,

                          ThreadFactory threadFactory,

                          RejectedExecutionHandler handler)

各个字段含义如下:

(1)corePoolSize: 线程池中的线程个数

(2)maximumPoolSize: 线程池中的允许最大线程个数

(3)keepAliveTime & unit: 当线程池中某个线程空闲时间大于该值,则回收,释放资源给OS,注意:这个只会释放多于corePoolSize的线程, 如要释放coreThread需调用:allowCoreThreadTimeOut(true)

(4)workQueue:当线程池中的线程都处于运行状态,则新加入的job将会放入到workQueue中等待执行

(5)threadFactory: 创建线程的工厂类

(6)handler: 当workQueue满了,而且线程池中线程数已经大于maximumPoolSize,此时,新加入的job将不会被正常执行,转而由handler来执行,这种情况下job将不会得到正常执行。

 

总体而言,整个ThreadPoolExecutor是个典型的生产者-消费者模式,它的工作流程如下:

1. 当线程池中线程数少于corePoolSize, 每收到一个job,则创建一个新的线程来执行

2. 当线程池中线程数等于corePoolSize,每收到一个job,将此job加入到workQueue

3. 当workQueue也满了,则每收到一个job,创建一个线程来执行,直到线程池中的线程数达到maximumPoolSize

4. 当workQueue满了而且线程池中线程数也达到了maximumPoolSize,则新加入的job将会不被执行,转由handler来执行

 

所以不同的BlockingQueue会影响ThreadPoolExecutor的执行:

1.ArrayBlockingQueue,有界队列,内存中顺序存储,它严格按照上面流程来工作

2.LinkedBlockingQueue, 默认情况下无界队列,这种情况下maximumPoolSize将不起作用,线程池中将用于只有corePoolSize个线程在工作,job来者照收,全部放入到workQueue直到撑爆堆内存(如果线程执行不快)

3.SynchronousQueue, 这种队列有个特性,加入其中的job只有被线程执行了,才会接受下一个job,所以一般情况下需要将maximumPoolSize设置很大,这样,同一时间会创建很多线程来执行不同的job,流程如下:此时,线程池中已经有corePoolSize个线程在运行了,来个job A和job B,job A放入到SynchronousQueue,按照此队列的特性,job B放不进去(等价于workQueue满了),按照流程3,要创建线程数来执行job B,所以,如果maximumPoolSize不维持一个比较大的数,则会进入流程4。在权衡资源的情况下,这种队列的线程池的执行效率会非常高,同时CPU也会非常的忙。

 

所以,按照上面逻辑,看下几种常用的ThreadPoolExecutor:

newSingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {

    return new FinalizableDelegatedExecutorService

        (new ThreadPoolExecutor(1, 1,

                                0L, TimeUnit.MILLISECONDS,

                                new LinkedBlockingQueue<Runnable>()));

}

特点:同一时间,线程池中永远只有一个线程在执行,其它都在workqueue中休息,CPU利用率太低, 因为是LinkedBlockingQueue,可能会耗尽内存

newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {

    return new ThreadPoolExecutor(nThreads, nThreads,

                                  0L, TimeUnit.MILLISECONDS,

                                  new LinkedBlockingQueue<Runnable>());

}

特点:同一时间,线程池中永远只有N个线程在执行,其它都在workqueue中休息,因为是LinkedBlockingQueue,可能会耗尽内存

newCachedThreadPool

public static ExecutorService newCachedThreadPool() {

    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

                                  60L, TimeUnit.SECONDS,

                                  new SynchronousQueue<Runnable>());

}

特点:同一时间,线程池中最多有无限个线程在执行,至多一个等待线程,CPU利用率高,可能会耗尽内存,但是不见得效率高

 

其它自定义的实现BlockingQueue接口的workQueue具体情况具体分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值