VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > 简明python教程 >
  • 简单看看ThreadPoolExecutor原理

线程池的作用就不多说了,其实就是解决两类问题:一是当执行大量的异步任务时线程池能够提供较好的性能,在不使用线程池时,每当需要执行异步任务是需要直接new一个线程去执行,而线程的创建和销毁是需要花销的,而线程池中的线程是可复用的,不需要每次执行异步任务时都去创建和销毁线程;二是线程池提供了一种资源限制和管理的手段,比如可以限制线程的个数、动态新增线程等;

 

一.Executors工具类

  我们创建一个线程池最好直接用这个工具类去创建,常用的线程池有几种,一种是用newFixedThreadPool方法创建固定大小的线程池,一种是newSingleThreadExecutor方法创建单线程的线程池,一种是newCachedThreadPool方法创建线程最多个数为Integer.MAX_VALUE的线程池,还有一些其他的线程池;

  看一下Executors工具类中一些重要的方法,先是newFixedThreadPool方法,只看这个,我们可以实际的线程池类型是ThreadPoolExecutor,而且内部是以LinkedBlockingQueue这个并发队列实现的,前面说过,这是一个有界阻塞队列,底层是一个单向链表,入队和出队是用独占锁实现的一个生产者消费者模式,比较容易;

 

  newSingleThreadExecutor方法,其实可以看到就是用上面的这种线程池实现的,只不过限制了线程池中线程必须只能是一个;

 

  newCachedThreadPool方法,这种线程池也是以最上面的那种形式实现的,只不过限制了最大的数量是Integer.MAX_VALUE

 

  由上面可知,三种其实都是以ThreadPoolExecutor实现的,所以我们了解这个类的实现机制就行了;

 

二.简单看看ThreadPoolExecutor结构

  先看看其中的属性,比较多:

复制代码
public class ThreadPoolExecutor extends AbstractExecutorService {
    //这个原子变量用于记录线程池的状态和其中线程的数量,
    //就类似读写锁里面一个int变量,高16位表示读锁的获取次数,低16位表示某一个线程获取写锁的可重入次数
    //在线程池这里,高3位表示线程池状态,后面的29位表示线程池线程数量,默认线程池状态是RUNNING,线程数量为0
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    //这里叫做线程个数掩码位数,举个例子,线程状态为STOP时,即1<<(32-3),也就是1<<29,用二进制表示00100000 00000000 00000000 00000000
    //可以知道在原子变量中高3位是001
    private static final int COUNT_BITS = Integer.SIZE - 3;
    //线程池中线程的最大容量,其实就是00011111 11111111 11111111 11111111
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    //高三位都是1,其他的29位都是0
    private static final int RUNNING    = -1 << COUNT_BITS;
    //都是0
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    //高三位是001,其他的29位都是0
    private static final int STOP       =  1 << COUNT_BITS;
    //高三位是010,其他的29位都是0
    private static final int TIDYING    =  2 << COUNT_BITS;
    //高三位是011,其他的29位都是0
    private static final int TERMINATED =  3 << COUNT_BITS;
    //这里用位运算,取高三位,表示运行状态CAPACITY为:00011111 11111111 11111111 11111111
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    //取低29位,表示线程个数
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    //这个方法用于计算原子变量ctl的值
    private static int ctlOf(int rs, int wc) { return rs | wc; }

    //判断线程池状态是否是RUNNING,直接判断高三位是不是小于0就行了
    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }

    //CAS使得低29位加一,表示线程池中线程数量加一
    private boolean compareAndIncrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect + 1);
    }

    //线程池中线程数量减一
    private boolean compareAndDecrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect - 1);
    }

    //底层实现就是这个有界阻塞队列,前面已经说过这个队列的原理了,这个队列汇中存放的是实现了Runnable接口的任务
    private final BlockingQueue<Runnable> workQueue;
    //独占锁用于控制添加Worker到集合workers中
    private final ReentrantLock mainLock = new ReentrantLock();
    //用于存放worker,这里封装着线程和任务
    private final HashSet<Worker> workers = new HashSet<Worker>();
    //条件变量
    private final Condition termination = mainLock.newCondition();
    //
      



  

相关教程