线程池-ExecutorService

关闭一个ExecutorService,有两个方法可以使用–shutdown和shutdownNow。
shutdown在关闭线程池前,会等待所有线程执行完;shutdownNow会立刻关闭线程池,并停止所有线程。

isTerminated();判断线程池中是否所有的任务都完成执行。必须先执行关闭方法shutdown或shutdownNow,否则这个方法只会返回false。

boolean awaitTermination(long timeout, TimeUnit unit)在发起shutdown请求后,阻塞当前线程直到线程池内所有线程执行完成,或者当前线程被中断,或者超时。

Future submit(Callable task); 提交一个任务给线程池,返回一个Future对象,调用get方法,如果目标线程没有执行完,则会阻塞。


获取一个线程池,使用Executors(该类不能被实例化)类,创建一个固定大小的线程池

 public static ExecutorService newFixedThreadPool(int nThreads) {
 //  池中corePoolSize ,池中的最大线程数,corePoolSize 之外的额外数量的空闲线程的存活时间,保存待执行的任务队列
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         *分为3步:
         *
         * 1. 线程池中运行的线程少于corePoolSize 的值,则新增一个worker到线程池中(调用 addWorker 会原子性的检查runState 和 workerCount, 以保证不会加入过量的线程)
         *
         * 2. 第一步失败了的话,task入队, 需要再次检查是否已经添加了一个线程或者线程池已经shutdown,检查状态,如果线程池停止了的话,就不入队了。
         *
         * 3. 如果不能入队,则尝试加入一个新线程.  如果失败, 说明线程池已经关闭或者饱和了(超过的线程池的最大值),拒绝此次任务.
         */
        int c = ctl.get();//初始值 101 0000....00
        if (workerCountOf(c) < corePoolSize) {
        //private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
        //CAPACITY     000 111....111
            if (addWorker(command, true))//会对ctl 加1
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {//线程池的线程数量超过了核心池的数量,就先入队列。
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))//入队列失败,则尝试新创建worker,此时不能超过线程池的最大值
            reject(command);
    }

addWorker方法,添加一个任务到线程池中,并启动。addWorker时要求同步(适应mainLock):

//只有线程池是running状态,才能添加任务。
private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);//通过位运算,取出状态位
            //Running 111  ,SHUTDOWN 000,STOP 001。

            // 如果线程池的状态不是RUNNING,也不是shutdown的话,直接返回false.(TERMINATED ,TIDYING,STOP)
            //如果是shutdown状态,firstTask 不是Null也就是说队列中还有任务,也直接返回false
            //如果是shutdown状态,firstTask 是Null,队列是空的,也返回false
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);//如果发现ctl>corePoolSize ,也返回false
                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,woker的达到过的最大值
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

每一个worker的run线程,调用了runWorker方法,woker如果创建时属于core线程,则第一个任务task就是创建时传的参数,执行完当前任务之后,它会从workers队列中取出下一个任务接着执行:

 public void run() {
            runWorker(this);
        }

final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                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();
                    } 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);
        }
    }

woker在执行前,需要同步,同步会先尝试获取锁,在没有被占用的情况下才能获得,如果锁被占用也就是state!=0,则会入队并阻塞(阻塞前还会尝试再判断是不是队列头,然后尝试获取锁);

protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

直接使用execute执行任务,是没有返回值的,如果要获取结果,那么使用submit方法,submit方法最后一个调用了execute来执行任务的,只是它对task做了一层包装,包装后的futureTask类有3个重要的方法,run方法,get方法,cancell方法。

首先是run方法,判断状态,所以这种任务只能执行一次。

 public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }
protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

线程启动失败的话,tryTerminate();该方法在中断前,会判断队列中是否有任务没有被执行,如果有,就什么都不做。没有额外任务的话,会优先关闭一个空闲线程,是否关闭所有的空闲线程,可以根据ONLY_ONE属性设置。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值