Java线程池ThreadPoolExecutor的execute()原理

从线程提交任务的submit方法说起
        众所周知,Java的线程池底层是使用工作队列+阻塞队列来实现的。
当工作队列(workQueue)任务数大于线程池的最大线程数时,任务阻塞,被放入一个阻塞队列(blockingQueue)中。
        那么,在任务提交到线程开始工作这段时间里发生了什么呢?
         下面是submit方法的源码,对Runnable接口的对象进行类封装,最后通过execute方法执行任务。
1
/**
2
     * @throws RejectedExecutionException {@inheritDoc}
3
     * @throws NullPointerException       {@inheritDoc}
4
     */
5
    public Future submit(Runnable task) {
6
        if (task == null) throw new NullPointerException();
7
        RunnableFuture<Void> ftask = newTaskFor(task, null);
8
        execute(ftask);
9
        return ftask;
10
    }
          我们来看看execute方法是怎么执行任务的(ThreadPoolExecutor.java)
1
/**
2
     * Executes the given task sometime in the future.  The task
3
     * may execute in a new thread or in an existing pooled thread.
4
     *
5
     * If the task cannot be submitted for execution, either because this
6
     * executor has been shutdown or because its capacity has been reached,
7
     * the task is handled by the current {@code RejectedExecutionHandler}.
8
     *
9
     * @param command the task to execute
10
     * @throws RejectedExecutionException at discretion of
11
     *         {@code RejectedExecutionHandler}, if the task
12
     *         cannot be accepted for execution
13
     * @throws NullPointerException if {@code command} is null
14
     */
15
    public void execute(Runnable command) {
16
        if (command == null)
17
            throw new NullPointerException();
18
        /*
19
         * Proceed in 3 steps:
20
         *
21
         * 1. If fewer than corePoolSize threads are running, try to
22
         * start a new thread with the given command as its first
23
         * task.  The call to addWorker atomically checks runState and
24
         * workerCount, and so prevents false alarms that would add
25
         * threads when it shouldn't, by returning false.
26
         *
27
         * 2. If a task can be successfully queued, then we still need
28
         * to double-check whether we should have added a thread
29
         * (because existing ones died since last checking) or that
30
         * the pool shut down since entry into this method. So we
31
         * recheck state and if necessary roll back the enqueuing if
32
         * stopped, or start a new thread if there are none.
33
         *
34
         * 3. If we cannot queue task, then we try to add a new
35
         * thread.  If it fails, we know we are shut down or saturated
36
         * and so reject the task.
37
         */
38
        int c = ctl.get();//计算工作线程的数量
39
        if (workerCountOf(c) < corePoolSize) {//比较核心线程数和工作线程数的大小
40
            if (addWorker(command, true))//工作线程数少,说明有线程空闲,不需要另外开启线程,直接往工作队列里添加线程即可
41
                return;
42
            c = ctl.get();
43
        }
44
        if (isRunning(c) && workQueue.offer(command)) {
45
            int recheck = ctl.get();
46
            if (! isRunning(recheck) && remove(command))//双重检查是否应该新建线程
47
                reject(command);
48
            else if (workerCountOf(recheck) == 0)
49
                addWorker(null, false);//可以创建新线程
50
        }
51
        else if (!addWorker(command, false))
52
            reject(command);//队列已满,拒绝创建新线程
53
    }
              那么是怎么创建新线程的呢?一起奥秘都在addWorker这个方法里:
1
/**
2
     * Checks if a new worker can be added with respect to current
3
     * pool state and the given bound (either core or maximum). If so,
4
     * the worker count is adjusted accordingly, and, if possible, a
5
     * new worker is created and started, running firstTask as its
6
     * first task. This method returns false if the pool is stopped or
7
     * eligible to shut down. It also returns false if the thread
8
     * factory fails to create a thread when asked.  If the thread
9
     * creation fails, either due to the thread factory returning
10
     * null, or due to an exception (typically OutOfMemoryError in
11
     * Thread.start()), we roll back cleanly.
12
     *
13
     * @param firstTask the task the new thread should run first (or
14
     * null if none). Workers are created with an initial first task
15
     * (in method execute()) to bypass queuing when there are fewer
16
     * than corePoolSize threads (in which case we always start one),
17
     * or when the queue is full (in which case we must bypass queue).
18
     * Initially idle threads are usually created via
19
     * prestartCoreThread or to replace other dying workers.
20
     *
21
     * @param core if true use corePoolSize as bound, else
22
     * maximumPoolSize. (A boolean indicator is used here rather than a
23
     * value to ensure reads of fresh values after checking other pool
24
     * state).
25
     * @return true if successful
26
     */
27
    private boolean addWorker(Runnable firstTask, boolean core) {
28
        retry:
29
        for (;;) {//死循环里判断线程池状态
30
            int c = ctl.get();
31
            int rs = runStateOf(c);
32
33
            // Check if queue empty only if necessary.
34
            if (rs >= SHUTDOWN &&
35
                ! (rs == SHUTDOWN &&
36
                   firstTask == null &&
37
                   ! workQueue.isEmpty()))
38
                return false;
39
            //内层死循环,workCount数量加一
40
            for (;;) {
41
                int wc = workerCountOf(c);
42
                if (wc >= CAPACITY ||
43
                    wc >= (core ? corePoolSize : maximumPoolSize))
44
                    return false;
45
                if (compareAndIncrementWorkerCount(c))
46
                    break retry;
47
                c = ctl.get();  // Re-read ctl
48
                if (runStateOf(c) != rs)
49
                    continue retry;
50
                // else CAS failed due to workerCount change; retry inner loop
51
            }
52
        }
53
54
        boolean workerStarted = false;
55
        boolean workerAdded = false;
56
        Worker w = null;
57
        try {
58
            w = new Worker(firstTask);
59
            final Thread t = w.thread;
60
            if (t != null) {
61
                final ReentrantLock mainLock = this.mainLock;
62
                mainLock.lock();
63
                try {
64
                    // Recheck while holding lock.
65
                    // Back out on ThreadFactory failure or if
66
                    // shut down before lock acquired.
67
                    int rs = runStateOf(ctl.get());
68
69
                    if (rs < SHUTDOWN ||
70
                        (rs == SHUTDOWN && firstTask == null)) {
71
                        if (t.isAlive()) // precheck that t is startable
72
                            throw new IllegalThreadStateException();
73
                        workers.add(w);
74
                        int s = workers.size();
75
                        if (s > largestPoolSize)
76
                            largestPoolSize = s;
77
                        workerAdded = true;
78
                    }
79
                } finally {
80
                    mainLock.unlock();
81
                }
82
                 //如果往HashSet中添加worker成功,启动线程
83
                if (workerAdded) {
84
                    t.start();
85
                    workerStarted = true;
86
                }
87
            }
88
        } finally {
89
            if (! workerStarted)
90
                addWorkerFailed(w);
91
        }
92
        return workerStarted;
93
    }
94
参考资料:http://www.cnblogs.com/trust-freedom/p/6681948.html











你可能感兴趣的:(Java基础,Java多线程,Java高并发)