JDK线程池源码分析

来源:互联网 发布:unity3d沙盒 编辑:程序博客网 时间:2024/06/11 22:22

在ThreadPoolExecutor类中,最核心的任务提交方法是execute()方法,虽然通过submit也可以提交任务,但是实际上submit方法里面最终调用的还是execute()方法,:

    public void execute(Runnable command) {        if (command == null)            throw new NullPointerException();        //第一个if条件(poolSize >= corePoolSize) 线程池中当前线程数>=核心池大小  则将任务放入任务缓存队列        //第二个if条件 线程池中当前线程数<核心池大小  则将创建Worker(任务执行线程)线程并start Worker,work不断的取任务执行(执行任务run方法)        if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {            if (runState == RUNNING && workQueue.offer(command)/*将任务放入任务缓存队列*/) {                if (runState != RUNNING || poolSize == 0)                    ensureQueuedTaskHandled(command);            }            else if (!addIfUnderMaximumPoolSize(command))                reject(command); // is shutdown or saturated        }    }


private boolean addIfUnderCorePoolSize(Runnable firstTask) {    Thread t = null;    final ReentrantLock mainLock = this.mainLock;    mainLock.lock();    try {    //线程池中当前线程数<核心池大小 创建Worker(任务执行线程)线程并start Worker        if (poolSize < corePoolSize && runState == RUNNING)            t = addThread(firstTask);        //创建线程去执行firstTask任务           } finally {        mainLock.unlock();    }    if (t == null)        return false;    t.start();//work不断的取任务执行(执行任务run方法)    return true;}



<pre name="code" class="java" style="font-size: 14px; line-height: 28px;">addIfUnderCorePoolSize(command) 是启动工作线程Worker的地方,我们提交的<span style="font-family: Verdana, Arial, Helvetica, sans-serif;">execute(Runnable command) 的</span><pre name="code" class="java" style="font-size: 14px; line-height: 28px;"><span style="font-family: Verdana, Arial, Helvetica, sans-serif;">Runnable 对象,最后被当作普通对象而非线程来使用的,调用run.</span>
<span style="font-family: Verdana, Arial, Helvetica, sans-serif;"></span>
<span style="font-family: Verdana, Arial, Helvetica, sans-serif;"></span>

Worker类的实现:


  private final class Worker implements Runnable {        private final ReentrantLock runLock = new ReentrantLock();        private Runnable firstTask;        volatile long completedTasks;        Thread thread;        Worker(Runnable firstTask) {            this.firstTask = firstTask;        }        boolean isActive() {            return runLock.isLocked();        }        void interruptIfIdle() {            final ReentrantLock runLock = this.runLock;            if (runLock.tryLock()) {                try {            if (thread != Thread.currentThread())            thread.interrupt();                } finally {                    runLock.unlock();                }            }        }        void interruptNow() {            thread.interrupt();        }        //运行任务        private void runTask(Runnable task) {            final ReentrantLock runLock = this.runLock;            runLock.lock();            try {                if (runState < STOP &&                    Thread.interrupted() &&                    runState >= STOP)                boolean ran = false;                beforeExecute(thread, task);   //beforeExecute方法是ThreadPoolExecutor类的一个方法,没有具体实现,用户可以根据                //自己需要重载这个方法和后面的afterExecute方法来进行一些统计信息,比如某个任务的执行时间等                           try {                    task.run();  //把我们提交的Runnable对象当普通对象来使                    ran = true;                    afterExecute(task, null);                    ++completedTasks;                } catch (RuntimeException ex) {                    if (!ran)                        afterExecute(task, ex);                    throw ex;                }            } finally {                runLock.unlock();            }        }             public void run() {            try {                Runnable task = firstTask;                firstTask = null;                //去任务  return workQueue.take();                while (task != null || (task = getTask()) != null) {                    runTask(task);  //运行任务                    task = null;                }            } finally {                workerDone(this);   //当任务队列中没有任务时,进行清理工作                   }        }    }


总结:

0 0