线程池工作原理

版权声明:如需转载,请附上原文链接即可 https://blog.csdn.net/doujinlong1/article/details/84623184

线程池工作原理

线程池状态的切换:

imageeab94eeb0c5c7d24.png

线程池关键类的uml图:

image.png

线程池就是把任务提交和任务执行解耦。

首先看一下线程池的使用:

public static void main(String args[]) throws InterruptedException {
	ExecutorService es = Executors.newFixedThreadPool(10);//1,创建线程池
	es.submit(()->{System.out.println("执行任务");});//2,提交任务
	es.shutdown();//3,线程池关闭
}

跟进源码:

1,创建线程池:

(可以看出来只是对线程池对象ThreadPoolExecutor属性的赋值)

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


public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

几个重要的参数:

基本大小,corePoolSize 基本的工作线程数。

最大大小 maximumPoolSize 当工作线程大于core,且workQueue也满了的情况下(arrayQueue),可以创建的最大工作线程。

保持存活时间 keepAliveTime 阻塞队列poll时的延时值,即如果线程在这个时间内仍然拿不到可以工作的任务,则杀死线程。

阻塞队列 workQueue 工作大于等于coreSize时用来阻塞的阻塞队列

线程工厂 threadFactory 生成新线程的工厂类

拒绝策略 rejectedExecutionHandler 线程池停止或者满了的时候的拒绝策略类

2,提交任务

提交任务的关键思路

submit时如果状态合适,会创建执行线程,去执行任务。
或者是运行状态下,工作线程已经大于等于coreSize的线程,则会放入到阻塞队列,等待有空闲下来的线程来执行。

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);//创建一个 FutureTask
    execute(ftask);//提交任务
    return ftask;//返回future
}


public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    /*
     * Proceed in 3 steps:
     *
     * 1. If fewer than corePoolSize threads are running, try to
     * start a new thread with the given command as its first
     * task.  The call to addWorker atomically checks runState and
     * workerCount, and so prevents false alarms that would add
     * threads when it shouldn't, by returning false.
     *
     * 2. If a task can be successfully queued, then we still need
     * to double-check whether we should have added a thread
     * (because existing ones died since last checking) or that
     * the pool shut down since entry into this method. So we
     * recheck state and if necessary roll back the enqueuing if
     * stopped, or start a new thread if there are none.
     *
     * 3. If we cannot queue task, then we try to add a new
     * thread.  If it fails, we know we are shut down or saturated
     * and so reject the task.
     */
    int c = ctl.get();
	//提交一个任务,如果工作线程数小于coreSize,则直接加入一个worker。加入失败则继续
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
        c = ctl.get();
    }
	//二次检查,如果线程池是运行状态,则把command加入阻塞队列中。
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();
		//如果不是运行状态,从queue去除。
        if (! isRunning(recheck) && remove(command))
            reject(command);
		//如果是运行,且没有工作线程,增加一个worker。
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }
	
	//如果不能加入,则拒绝。(队列已满,尝试再加入,如果加入失败,则拒绝)
    else if (!addWorker(command, false))
        reject(command);
}



private boolean addWorker(Runnable firstTask, boolean core) {
    retry:
    for (;;) {
        int c = ctl.get();
        int rs = runStateOf(c);

        // Check if queue empty only if necessary.
		//判断是否状态不为running  并且 (状态不为SHUTDOWN || firstTask不为null ||  workQueue为空)
		//如果满足,直接return。不做任何事情
        if (rs >= SHUTDOWN &&
            ! (rs == SHUTDOWN &&
               firstTask == null &&
               ! workQueue.isEmpty()))
            return false;

        for (;;) {
            int wc = workerCountOf(c);
			//如果工作线程已经大于最大数量或者 大于core或max,则return。
            if (wc >= CAPACITY ||
                wc >= (core ? corePoolSize : maximumPoolSize))
                return false;
			//cas增加工作线程数,增加成功跳出大循环
            if (compareAndIncrementWorkerCount(c))
                break retry;
			//增加失败,继续判断状态,继续循环
            c = ctl.get();  // Re-read ctl
            if (runStateOf(c) != rs)
                continue retry;
            // else CAS failed due to workerCount change; retry inner loop
        }
    }

    boolean workerStarted = false;
    boolean workerAdded = false;
    Worker w = null;
    try {
		//创建新的Worker
        w = new Worker(firstTask);
		//线程工厂创建出一个有着传入任务firstTask的线程
        final Thread t = w.thread;
        if (t != null) {
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                // Recheck while holding lock.
                // Back out on ThreadFactory failure or if
                // shut down before lock acquired.
                int rs = runStateOf(ctl.get());
				//如果线程池为running或者为shutdown并且firstTask为null(关闭前提交任务)
                if (rs < SHUTDOWN ||
                    (rs == SHUTDOWN && firstTask == null)) {
					//如果t已经启动,则抛出异常。
                    if (t.isAlive()) // precheck that t is startable
                        throw new IllegalThreadStateException();
					//workers增加线程w
                    workers.add(w);
                    int s = workers.size();
					//
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
			//如果加入到workers,则启动。
            if (workerAdded) {
                t.start();
                workerStarted = true;
            }
        }
    } finally {
		//如果启动失败,没有调用start方法时,则原子操作减去workCount,从workers移除。
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;
}

2.1 worker的执行

 public void run() {
        runWorker(this);
 }


final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
	//获取worker里面的任务。
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // allow interrupts
    boolean completedAbruptly = true;
    try {
		//如果task为null时则去workqueue里去取任务,直到取完,则关闭这个工作线程。
        while (task != null || (task = getTask()) != null) {
            w.lock();
            // If pool is stopping, ensure thread is interrupted;
            // if not, ensure thread is not interrupted.  This
            // requires a recheck in second case to deal with
            // shutdownNow race while clearing interrupt
			//如果线程池正在关闭,确保线程被 interrupted,如果没有,确保线程没有被 interrupted,这个需要二次检查防止调用shutdownNow 时正在interrupt。
			//判断如果状态已经是stop,或者 当前线程已经被打断并且线程状态已经是stop并且workers还没有被关闭。 调用interrupt
            if ((runStateAtLeast(ctl.get(), STOP) ||
                 (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) &&
                !wt.isInterrupted())
                wt.interrupt();
            try {
				//模板方法,前置调用
                beforeExecute(wt, task);
                Throwable thrown = null;
                try {
					//调用run方法,执行任务。
                    task.run();
                } catch (RuntimeException x) {
                    thrown = x; throw x;
                } catch (Error x) {
                    thrown = x; throw x;
                } catch (Throwable x) {
                    thrown = x; throw new Error(x);
                } finally {
					//模板方法,后置调用
                    afterExecute(task, thrown);
                }
            } finally {
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
		//执行结束后操作
        processWorkerExit(w, completedAbruptly);
    }
}
//
 private Runnable getTask() {
    boolean timedOut = false; // Did the last poll() time out?

    for (;;) {
        int c = ctl.get();
        int rs = runStateOf(c);
		
        // Check if queue empty only if necessary.
		//如果已经关闭了且任务阻塞队列为空,则减去工作线程数。不返回任务。(因为没任务)
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }
		
        int wc = workerCountOf(c);

        // Are workers subject to culling?
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
		//如果工作线程数已经大于最大数目并且 (工作线程数大于1或者工作队列为空),cas减去工作线程数,返回。
        if ((wc > maximumPoolSize || (timed && timedOut))
            && (wc > 1 || workQueue.isEmpty())) {
            if (compareAndDecrementWorkerCount(c))
                return null;
            continue;
        }

        try {
			//判断是否容许延时取出,如果allowCoreThreadTimeOut为真或者 工作线程数大于coreSize,则延时取出,否则一直等待取出。
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();
			//自旋等待r不为null的任务
            if (r != null)
                return r;
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}


private void processWorkerExit(Worker w, boolean completedAbruptly) {
    if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
        decrementWorkerCount();//如果执行失败,则减去worker数目

    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        completedTaskCount += w.completedTasks;
		//从workers中移除需要执行的任务w
        workers.remove(w);
    } finally {
        mainLock.unlock();
    }
	如果执行完成时线程池正在关闭,工作线程数为0,则把线程池状态置为终止terminate
    tryTerminate();
    int c = ctl.get();
    if (runStateLessThan(c, STOP)) {
		//正常执行完是false,则进入。
        if (!completedAbruptly) {
			//min为0或者coreSize。
            int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
			//如果min为0且阻塞队列不为空。则min置为1。
            if (min == 0 && ! workQueue.isEmpty())
                min = 1;
			如果工作线程数大于min,则不需要再增加工作线程,如果比min还小,则会走到下面的addWorker。
            if (workerCountOf(c) >= min)
                return; // replacement not needed
        }
        addWorker(null, false);
    }
}

3,线程池关闭

shutdown的操作

1判断shutdown权限

2修改线程池状态,不再接受新任务

3interrupt所有线程

4修改状态到terminal

public void shutdown() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
		//检查当前线程是否有能修改所有工作线程的权限
        checkShutdownAccess();
		//自旋 + cas 去修改线程池的状态。
        advanceRunState(SHUTDOWN);
		//尝试interrupt所有工作线程t.interrupt()            
		interruptIdleWorkers();
        onShutdown(); // hook for ScheduledThreadPoolExecutor
    } finally {
        mainLock.unlock();
    }
	
    tryTerminate();
}



final void tryTerminate() {
	//自旋,如果失败继续执行。
    for (;;) {
        int c = ctl.get();
		//如果是running或者已经是tidying或者terminate,则不用做操作。
        if (isRunning(c) ||
            runStateAtLeast(c, TIDYING) ||
            (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
            return;
		//如果工作线程不为0,则尝试interrupt后返回。
        if (workerCountOf(c) != 0) { // Eligible to terminate
            interruptIdleWorkers(ONLY_ONE);
            return;
        }

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {//将状态置为tidying然后调用模板方法 terminated,之后将状态置为terminated。
            if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                try {
                    terminated();
                } finally {
                    ctl.set(ctlOf(TERMINATED, 0));
                    termination.signalAll();
                }
                return;
            }
        } finally {
            mainLock.unlock();
        }
        // else retry on failed CAS
    }
}

猜你喜欢

转载自blog.csdn.net/doujinlong1/article/details/84623184