Java线程池框架源码分析(2)

Worker是ThreadPoolExecutor的一个内部类,Worker本身实现了Runnable接口,并封装了一个Thread对象,最后在构造方法中获取了一个Runnable对象,这个对象就是ThreadPoolExecutor通过execute提交过来的目标任务。

跟踪runWorker(this)方法:

final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock();
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {
                w.lock();

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();//在这里直接调用了目标任务的run方法,并没有将它传给Thread对象。
                    } 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);
        }
    }

回过头来在看看Worker的构造方法:

Worker(Runnable firstTask) {
        setState(-1);
        this.firstTask = firstTask;
        this.thread = getThreadFactory().newThread(this);
    }

它将自己传给了自己的成员变量thread。目标任务被执行的步骤可能就是:Worker的成员变量thread启动后调用worker的run方法,worker的run方法中将自己传给runWorker,runWorker在调用目标执行对象的run方法。

那么thread是何时被执行的呢?

下面看看ThreadPoolExecutor中的一个其他方法:

private boolean addWorker(Runnable firstTask, boolean core) {
      ......
        try {
            final ReentrantLock mainLock = this.mainLock;
            w = new Worker(firstTask);
            final Thread t = w.thread;//这里初始化一个Worker对象w,在将w的成员变量thread付给t
            if (t != null) {
                mainLock.lock();
                try {
                    int c = ctl.get();
                    int rs = runStateOf(c);

if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive())
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();//在这里调用t的start方法。
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

这里为什么会设计的这么绕,我想主要是Worker不仅封装了一个thread,而且对目标任务进行了封装,在运行封装过后的目标任务前,addWorker可以做一些相关操作。

这里仅仅介绍了ThreadPoolExecutor的线程池,那么这个线程池是如何被维护的,下面介绍几个关键的参数。

private volatile int corePoolSize;
  private volatile int maximumPoolSize;
  private final BlockingQueue<Runnable> workQueue;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/e281b0e157df4a3c7317cb6013e4eab7.html