Java线程池原理分析

【1.0】 Executors类提供了几种不同特性的线程池,其主要实现类都离不开ThreadPoolExecutor,先看一下ThreadPoolExecutor的构建方法

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

【1.1】 参数说明

corePoolSize保持最小的核心线程数,不会被回收,除非allowCoreThreadTimeOut被设置

maximumPoolSize 允许被执行时最大的线程数,当核心线程池数和队列满了,会加入最大线程数中执行

keepAliveTime 当线程数大于核心线程数,超过的线程保持的时间,和unit搭配使用

unit 缓存时间单位

workQueue任务队列,可进行任务阻塞等待,保存将要执行的队列

threadFactory创建新线程的的工厂对象

handler 线程数或者队列容量达到极限,造成线程池阻塞是的处理器

【1.2】 执行方法

当调用 execute() 方法添加一个任务时,线程池会做如下判断:

  1. 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
  2. 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列。
  3. 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建线程运行这个任务;
  4. 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异
public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
      
        int c = ctl.get();
        //检查执行任务数
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))//加入核心线程池执行
                return;
            c = ctl.get();
        }
        //判断线程池状态,加入任务队列
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            //判断线程池是否关闭
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))//加入队列失败,会加入最大线程数执行
            reject(command);
    }
    
    //  wc >= (core ? corePoolSize : maximumPoolSize))  线程数不超过maximumPoolSize

【1.3】 线程池会创建一样Worker来封装Thread,然后不断的执行队列的任务

private boolean addWorker(Runnable firstTask, boolean core) {

        ......

        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            //创建一个Worker
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    int rs = runStateOf(ctl.get());

                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    //启动线程
                    t.start();
                    workerStarted = true;
                }
            }

        ......
    }

【1.4】 Worker继承了Runnable的接口,在初始化的时候会设置到新建的线程,当start线程就中心runWorker,将不循环断获取任务列表的任务执行,代码如下

    private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable{
        
     Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }
        
    public void run() {
            runWorker(this);
        }

【1.5】 循环执行任务


final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            //循环获取任务,如果队列数据为空,线程会进入等待
            while (task != null || (task = getTask()) != null) {
                w.lock();
                ......
            }
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }

【2.0】 常用的任务队列

【2.1】 ArrayBlockingQueue 数组储存,有界队列,超过会从队头覆盖对象,FIFO

    final Object[] items;

    private void insert(E x) {
        items[putIndex] = x;
        //计算下个index
        putIndex = inc(putIndex);
        ++count;
        notEmpty.signal();
    }
    
    final int inc(int i) {
        return (++i == items.length) ? 0 : i;
    }

【2.2】 LinkedBlockingQueue 单向链表储存,有界列表,默认数是2的31次方2147483648,

    static class Node {
        E item;

        Node next;

        Node(E x) { item = x; }
    }
    
    public LinkedBlockingQueue() {
        this(Integer.MAX_VALUE);
    }

     public boolean offer(E e) {
        if (e == null) throw new NullPointerException();
        final AtomicInteger count = this.count;
        if (count.get() == capacity)
            return false;
        int c = -1;
        Node node = new Node(e);
        final ReentrantLock putLock = this.putLock;
        putLock.lock();
        try {
            if (count.get() < capacity) {
                enqueue(node);
                c = count.getAndIncrement();
                if (c + 1 < capacity)
                    notFull.signal();
            }
        } finally {
            putLock.unlock();
        }
        if (c == 0)
            signalNotEmpty();
        return c >= 0;
    }

【2.3】 DelayedWorkQueue 数组存储,队长可自增长,周期性任务使用

public boolean offer(Runnable x) {
            if (x == null)
                throw new NullPointerException();
            //对象必须的RunnableScheduledFuture的子类
            RunnableScheduledFuture e = (RunnableScheduledFuture)x;
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                int i = size;
                if (i >= queue.length)
                    grow();//自动增长
                size = i + 1;
                if (i == 0) {
                    queue[0] = e;
                    setIndex(e, 0);
                } else {
                    siftUp(i, e);
                }
                if (queue[0] == e) {
                    leader = null;
                    available.signal();
                }
            } finally {
                lock.unlock();
            }
            return true;
        }

【2.4】 SynchronousQueue使用队列或者栈进行储存

  public SynchronousQueue(boolean fair) {
        transferer = fair ? new TransferQueue() : new TransferStack();
    }

【3.0】 DefaultThreadFactory 线程创建工厂类

public Thread newThread(Runnable r) {
            //直接实例一个线程
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }

【4.0】 Executors为我们通过一些实例不同特性的线程池方法,主要有以下几个

【4.1】 Executors.newScheduledThreadPool() 可执行周期性任务的线程池
实例是ScheduledThreadPoolExecutor,ScheduledThreadPoolExecutor继承ThreadPoolExecutor,队列使用LinkedBlockingQueue

 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    
  public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
              new DelayedWorkQueue());
    }
    
    
      ScheduledFutureTask(Runnable r, V result, long ns, long period) {
            super(r, result);
            this.time = ns;//执行时间
            this.period = period;//重复次数
            this.sequenceNumber = sequencer.getAndIncrement();
        }

【4.2】 Executors.newCachedThreadPool()线程数可自动扩展,闲着线程60秒将会被回收

 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue());
    }

【4.3】 Executors.newFixedThreadPool() 执行固定线程数的线程池,核心线程数等于最大线程数,且有限,队列无限

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue());
    }

【4.4】 Executors.newSingleThreadExecutor() 单线程的线程池,FinalizableDelegatedExecutorService 只是包装了 ThreadPoolExecutor,对象在回收时会关闭线程池

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue()));
    }
    
     static class FinalizableDelegatedExecutorService
        extends DelegatedExecutorService {
        FinalizableDelegatedExecutorService(ExecutorService executor) {
            super(executor);
        }
        protected void finalize() {
            super.shutdown();
        }
    }

【4.5】 Executors.newSingleThreadScheduledExecutor()
具有单线程池和周期性的特点,线程池包装了ScheduledThreadPoolExecutor,

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1));
    }

你可能感兴趣的:(Java线程池原理分析)