学习ThreadPoolExecutor的一些思考

139 阅读2分钟

1. execute的执行的重点

  • poolSize < corePoolSize的时候,会创建线程
  • 如果pollSize >= corePoolSize,会尝试放到队列里面,如果能放到队列里面,就直接返回
  • 如果队列也放不下了,但是poolSize < maximumPoolSize,会执行addIfUnderMaximumPoolSize
  • 注意这里是个for (;;) ,也就是说,如果会执行addIfUnderMaximumPoolSize最后return的runnable != command时候,会进入下一次循环
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        for (;;) {
            if (runState != RUNNING) {
                reject(command);
                return;
            }
            if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
                return;
            if (workQueue.offer(command))
                return;
            Runnable r = addIfUnderMaximumPoolSize(command);
            if (r == command)
                return;
            if (r == null) {
                reject(command);
                return;
            }
            // else retry
        }
    }

2.线程池之所以是线程池

线程池之所以是线程池,是因为它可以使用少数几个线程来跑若干给runnable。 使之能工作的就是Worker这个内部类。


      /**
         * Main run loop
         */
        public void run() {
            try {
                Runnable task = firstTask;
                firstTask = null;
                while (task != null || (task = getTask()) != null) {
                    runTask(task);
                    task = null; // unnecessary but can help GC
                }
            } catch(InterruptedException ie) {
                // fall through
            } finally {
                workerDone(this);
            }
        }
        
        Runnable getTask() throws InterruptedException {
            for (;;) {
                switch(runState) {
                case RUNNING: {
                    if (poolSize <= corePoolSize)   // untimed wait if core
                        return workQueue.take();
                    
                    long timeout = keepAliveTime;
                    if (timeout <= 0) // die immediately for 0 timeout
                        return null;
                    Runnable r =  workQueue.poll(timeout, TimeUnit.NANOSECONDS);
                    if (r != null)
                        return r;
                    if (poolSize > corePoolSize) // timed out
                        return null;
                    // else, after timeout, pool shrank so shouldn't die, so retry
                    break;
                }
                //省略其他状态
                }
        }
        
        
        private void runTask(Runnable task) {
            final ReentrantLock runLock = this.runLock;
            runLock.lock();
            try {
                // Abort now if immediate cancel.  Otherwise, we have
                // committed to run this task.
                if (runState == STOP)
                    return;

                Thread.interrupted(); // clear interrupt status on entry
                boolean ran = false;
                beforeExecute(thread, task);
                try {
                    task.run();
                    ran = true;
                    afterExecute(task, null);
                    ++completedTasks;
                } catch(RuntimeException ex) {
                    if (!ran)
                        afterExecute(task, ex);
                    // Else the exception occurred within
                    // afterExecute itself in which case we don't
                    // want to call it again.
                    throw ex;
                }
            } finally {
                runLock.unlock();
            }
        }
  • Worker是一个Runnable,看它的run函数,就是不停地从队列中取runnable,然后runTask(runnable)
  • 我们可以使用corePoolSize数量的Worker来不停地运行queue中的runnable
  • keepAliveTime,空闲的Worker等待队列的时间,如果poolSize < corePoolSize的情况下,就一直等,否则如果超时了,Worker的run就return了,线程就会被销毁。