美文网首页
11、线程池之getTask

11、线程池之getTask

作者: kele2018 | 来源:发表于2020-03-17 15:27 被阅读0次

private Runnable getTask() {
       boolean timedOut = false; // Did the last poll() time out?
       for (;;) {
           int c = ctl.get();
           int rs = runStateOf(c);           /**如果线程池处于STOP、TIDYING、TERMINATED三种状态之一,或者处于SHUTDOWN状态且阻塞队列为空时,执行decrementWorkerCount(),并返回空任务*/
           if (rs >= SHUTDOWN ) {
               /**
               两种情况:1、关闭状态,此时看队列中是否有任务》return null  2、大于关闭》return null
               */
               if(rs >= STOP || workQueue.isEmpty()){
                   decrementWorkerCount();
               return null;  //worker就退出了
               }
              
           }
           int wc = workerCountOf(c);
           /**
            * 判断当前线程是否允许超时
            * 1.设置核心线程允许超时allowCoreThreadTimeOut
            * 2.线程池当前线程数超过核心线程数》》》》?????
            */
           boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
           /**
            * 判断当前线程是否可以退出
            * 第一步 判定当前线程是否符合退出的基本条件
            * 1.线程池线程数大于最大线程数 (为了保证线程池数量可控)或者
            * 2.当前线程允许超时并且已经超时(为了处理真正超时的线程)
            * 符合线程退出的基本条件以后再进行第二步的判断
            * 第二步,判定当前的线程池状态,是否可以支持线程退出
            * 1,线程池线程数 大于1 (不是最后一个线程就可以直接退出)或者
            * 2.线程池任务队列为空(相当于(wc <= 1 && workQueue.isEmpty()) 最后一个线程需要队列为空才可以退出)
            * 符合两步的条件的线程,可以正常退出
            */
           if ((wc > maximumPoolSize || (timed && timedOut))){
               if(wc > 1 || workQueue.isEmpty()){
                   if (compareAndDecrementWorkerCount(c)){
                       return null;
                   }
                continue;
               }
           }
              
           try {
                //worker线程会在这里阻塞等待获取任务,如果woker线程允许超时,则阻塞等待一段时间
               //不允许超时,则会一直阻塞在这里,直到能获取到任务
              //这里会响应中断,一旦线程池关闭,会中断worker线程,等待任务的阻塞状态将被打破
               Runnable r = timed ?
                   //不阻塞  到时间闪人
                   workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                   //阻塞
                   workQueue.take();
               if (r != null)
                   return r;
               timedOut = true;
           } catch (InterruptedException retry) {
               timedOut = false;
           }
       }
   }

相关文章

网友评论

      本文标题:11、线程池之getTask

      本文链接:https://www.haomeiwen.com/subject/tjptyhtx.html