Is ExecutorService (specifically ThreadPoolExecutor) thread safe?

后端 未结 6 2012
长情又很酷
长情又很酷 2020-11-27 05:26

Does the ExecutorService guarantee thread safety ?

I\'ll be submitting jobs from different threads to the same ThreadPoolExecutor, do I have to synchro

6条回答
  •  时光取名叫无心
    2020-11-27 05:45

    For ThreadPoolExecutor, it submit is thread safe. You can see the source code in jdk8. When adding a new task, it uses a mainLock to ensure the thread safe.

    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);
                    final Thread t = w.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;
            }
    

提交回复
热议问题