线程池复用原理

伪代码

    
    static List  rList =new ArrayList<>();//用来保存task的队列
    public static void main(String[] args) throws Exception {
         
        for( int  a=0;a<10;a++) {
            rList.add(new Test().new Run(a));
        }
        Thread thread   =new Thread(new Test().new  MyRun()); //创建线程,线程池当中是进行了一次封装将 有个worker 类,该类实现了Runnable 接口,同时持有Thread 对象,在内部实例化Thread 的时候,将自身当做Runnable 传给了内部的Thread 对象,后续的工作就是在这个类的run()中进行了
        thread.start();;
    }

 
    class MyRun implements Runnable{  //thread 传入的Runnable 
        @Override
        public void run() {// 当thread.start() 后这个run()就会得到执行,在这个方法的内部循环task队列,直接调用task 的run()
            // TODO Auto-generated method stub
            for(int i=0;i
  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);
    }

addWorker()

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

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                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 {
            w = new Worker(firstTask); //实例化 Worker 类
            final Thread t = w.thread; //创建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());

                    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;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

看下Worker 类,worker 类本身是一个Runnable

  Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this); // 这里创建了Thread ,并将this 传入,上面说过,Worker 本身就是一个Runnable 对象
        }
 //既然是一个Runnable ,必然复写了run()
 public void run() {
            runWorker(this);
        }

    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();
                // 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
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        task.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);
        }
    }

getTask()

// 为分析而简化后的代码
private Runnable getTask() {
    boolean timedOut = false;
    for (;;) {
        int c = ctl.get();
        int wc = workerCountOf(c);

        // timed变量用于判断是否需要进行超时控制。
        // allowCoreThreadTimeOut默认是false,也就是核心线程不允许进行超时;
        // wc > corePoolSize,表示当前线程池中的线程数量大于核心线程数量;
        // 对于超过核心线程数量的这些线程,需要进行超时控制
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

        if (timed && timedOut) {
            // 如果需要进行超时控制,且上次从缓存队列中获取任务时发生了超时,那么尝试将workerCount减1,即当前活动线程数减1,
            // 如果减1成功,则返回null,这就意味着runWorker()方法中的while循环会被退出,其对应的线程就要销毁了,也就是线 
  程池中少了一个线程了
            if (compareAndDecrementWorkerCount(c))
                return null;
            continue;
        }

        try {
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();

            // 注意workQueue中的poll()方法与take()方法的区别
            //poll方式取任务的特点是从缓存队列中取任务,最长等待keepAliveTime的时长,取不到返回null(当timed 为true的时候,就说明当前线程数大于核心线程数,这个时候需要考虑是否需要销毁线程,等keepAliveTime时间后如果返回null就表明需要销毁该线程了)
            //take方式取任务的特点是从缓存队列中取任务,若队列为空,则进入阻塞状态,直到能取出对象为止(线程池中的线程数小于核心线程数,说明很闲,只需要获取任务即可)

            if (r != null)
                return r;
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

总结:Thread.start() 会执行传入Runnable 的run(),同时执行完后,当前THread 就结束了,这怎么实现复用呢?多线可能会有多个Runnable 啊,每次执行完就结束了那岂不是每一个Runnable 都要重新new Thread(runable),这跟自己new Thread 有什么区别?其实线程池创建的Thead 传入的Runnable 并不是我们传入的task Runanble, 而是其内部一个封装的一个Worker 类,我们创建的Runnable 并没有被当做参数传入到Runnable 中,而是被加入到对比当中,在worker 这个runnable 的run()中去循环取出,就是让worker的run()内部执行while循环(循环任务队列,这样就能保证一直复用了),具体分 poll(),和take()两种形式,来区分该线程是否需要被销毁,同时也说明核心线程的其实就是最后活下来的那几个线程

参考:https://blog.csdn.net/MingHuang2017/article/details/79571529

你可能感兴趣的:(线程池复用原理)