澳门网络娱乐游戏平台-澳门电子游戏娱乐网址-官方直营

澳门网址网站导航大全ThreadPoolExecutor 学习笔记

线程池的奥义

  在开辟顺序的经过中,相当多时候大家会遇见蒙受批量试行职务的情景,当各样具体义务之间交互作用独立并不依赖其余职务的时候,大家会考虑选取并发的不二秘籍,将逐个职务分散到分化的线程中开展履行来进步任务的进行效能。

  大家会想到为各类任务都分配一个线程,不过如此的做法存在异常的大的问题:

  1、能源消耗:首先当职责数量大幅度的时候,大量线程会攻下多量的系统能源,特别是内部存款和储蓄器,当线程数量超越CPU可用数量时,空闲线程会浪费形成内部存款和储蓄器的浪费,并加大GC的下压力,大批量的线程以致会平素产生程序的内部存款和储蓄器溢出,何况多量线程在竞争CPU的时候会带来额外的性子开销。假设CPU已经足足费劲,再多的线程不止不会提升质量,反而会稳中有降品质。

  2、线程生命周期的付出:线程的创造和销毁都以有代价的,线程的创办须要时刻、延迟处理的央求、供给JVM和操作系统提供部分帮衬操作。假诺央求特别庞大,而且任务的举办极度轻量级(举个例子只是总结1+1),那么比较下来创制和销毁线程代价就太高昂了。

  3、稳定性:如资源消耗中所说风流倜傥旦程序因为大气的线程抛出OutOfMemoryEorror,会引致程序非常的大的不牢固。

  

  既然为各种职责分配三个线程的做法早已不可行,大家考虑的代替方法中就一定要构思到,1、线程不可能否无界定创造,数量必得有叁个相符的上限。2、线程的始建费用昂贵,那大家得以思量录用这么些线程。道理当然是那样的,池化本事是意气风发项相比便于想到的替代方案(放马后炮亮),线程的池化管理就叫线程池。

 

何以要用线程池?什么意况下才会用到线程池?

并发的线程数量过多,并且每一个线程都以实行一个年华非常的短的职务就停止了,那样频仍创立线程就能大大裁减系统的频率,因为一再创立线程和销毁线程供给时日。

就此,就用到了线程池;线程池中的线程能够复用,就是实践完贰个任务,并不被销毁,而是继续施行下二个职务。

正如使用线程:

public class Test{
  
   public static void main(String[] args) {
  
      long start = System.currentTimeMillis();
      for(int i=0;i<10000;i++){
        new Thread(new Runnable() {
  
           @Override
           public void run() {
  
              System.out.println(Thread.currentThread().getName());
           }
        }).start();
      }
      long end = System.currentTimeMillis();
      System.out.println("运行时间:"+(end-start)+"毫秒");
   }
  
}

新建10000个线程来施行职务,测量试验结果得出需求时间是0.7秒左右。

 

使用线程池:

public class ThreadPoolTest{
  
   private static int produceTaskSleepTime = 2;
    private static int produceTaskMaxNumber = 20;
  
    public static void main(String[] args) {
       int corePoolSize = 2;
      
        int maximumPoolSize = 4;
       
        long keepAliveTime = 3;
        
        int blockingQueueSize = 3;
        
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS,
             new LinkedBlockingQueue<Runnable>(blockingQueueSize),
                new ThreadPoolExecutor.CallerRunsPolicy());
        System.out.println(threadPool.getPoolSize());
        long start = System.currentTimeMillis();
        for (int i = 1; i <= produceTaskMaxNumber; i++){
            try{
               
                String task = "任务 #" + i;
                System.out.println("放入 " + task);
                threadPool.execute(new ThreadPoolTask(task));
            catch (Exception e){
                e.printStackTrace();
            }
        }
        
        System.out.println("关闭线程池");
        long end = System.currentTimeMillis();
      System.out.println("运行时间:"+(end-start)+"毫秒");
    }
  
}
public class ThreadPoolTask implements Runnable, Serializable {
   private static final long serialVersionUID = 0;
   private static int consumeTaskSleepTime = 2000;
   // 保存任务所需要的数据
   private Object threadPoolTaskData;
  
   ThreadPoolTask(Object tasks) {
      this.threadPoolTaskData = tasks;
   }
  
   public void run() {
      System.err.println("线程 " + Thread.currentThread().getName() + " 开始做 " + threadPoolTaskData);
      
      threadPoolTaskData = null;
   }
  
   public Object getTask() {
      return this.threadPoolTaskData;
   }
}

相似的使用线程池,只须求0.1秒左右的时日。十分轻便就能够开掘那四头中间的不一致。

 

1.ThreadPoolExecutor类

java.uitl.concurrent.ThreadPoolExecutor类是线程池中最宗旨的三个类,上面我们来看一下ThreadPoolExecutor类的有声有色达成源码(内容旧事JDK1.7卡塔尔(قطر‎。

在ThreadPoolExecutor类中提供了七个构造方法:

public class ThreadPoolExecutor extends AbstractExecutorService {
   .....
   public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
    ...
}

 从地点的代码能够摸清,ThreadPoolExecutor继承了AbstractExecutorService类,并提供了八个构造器,事实上,开采近日多少个构造器都是调用的第多个布局器进行的开始化专门的学业。

上面解释下一下构造器中相继参数的含义:

  • corePoolSize:线程池大旨线程大小。在开创了线程池后,私下认可情状下,线程池中并从未其他线程,而是等待有职务赶来才创制线程去实行任务,除非调用了prestartAllCoreThreads(卡塔尔(قطر‎也许prestartCoreThread(卡塔尔(英语:State of Qatar)方法,从那2个章程的名字就能够看看,是预创立线程的意趣,即在未曾经担职责赶来早先就创办corePoolSize个线程恐怕一个线程。暗许情形下,在创设了线程池后,线程池中的线程数为0,当有职务来现在,就能够成立一个线程去施行职务,当线程池中的线程数目到达corePoolSize后,就能够把达到的任务放到缓存队列当中;
  • maximumPoolSize:线程池最大线程数,表示在线程池中最多能创制几个线程;
  • keepAliveTime:表示线程未有职责执行时最多维持多长期小时会终止。默许情形下,独有当线程池中的线程数大于corePoolSize时,keepAlive提姆e才会起效果,直到线程池中的线程数不高于corePoolSize,即当线程池中的线程数大于corePoolSize时,若是三个线程空闲的时光达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。可是倘使调用了allowCoreThreadTimeOut(boolean卡塔尔国方法,在线程池中的线程数不高于corePoolSize时,keepAliveTime参数也会起效能,直到线程池中的线程数为0;
  • unit:参数的光阴单位,有7种取值,在TimeUnit类中有7种静态属性:

    TimeUnit.DAYS;               //天
    TimeUnit.HOURS;             //小时
    TimeUnit.MINUTES;           //分钟
    TimeUnit.SECONDS;           //秒
    TimeUnit.MILLISECONDS;      //毫秒
    TimeUnit.MICROSECONDS;      //微秒
    TimeUnit.NANOSECONDS;       //纳秒
    
  • workQueue:贰个不通队列,用来存款和储蓄等待实行的职分;

  • threadFactory:线程工厂,首要用以创制线程;
  • handler:表示当拒却管理职分时的国策,有以下三种取值:
    ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 
    ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
    ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务 
    

从ThreadPoolExecutor类能够清楚,ThreadPoolExecutor世袭了AbstractExecutorService,大家来看一下AbstractExecutorService的落到实处:

public abstract class AbstractExecutorService implements ExecutorService {

    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

    private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                            boolean timed, long nanos)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (tasks == null)
            throw new NullPointerException();
        int ntasks = tasks.size();
        if (ntasks == 0)
            throw new IllegalArgumentException();
        List<Future<T>> futures= new ArrayList<Future<T>>(ntasks);
        ExecutorCompletionService<T> ecs =
            new ExecutorCompletionService<T>(this);

        // For efficiency, especially in executors with limited
        // parallelism, check to see if previously submitted tasks are
        // done before submitting more of them. This interleaving
        // plus the exception mechanics account for messiness of main
        // loop.

        try {
            // Record exceptions so that if we fail to obtain any
            // result, we can throw the last exception we got.
            ExecutionException ee = null;
            long lastTime = timed ? System.nanoTime() : 0;
            Iterator<? extends Callable<T>> it = tasks.iterator();

            // Start one task for sure; the rest incrementally
            futures.add(ecs.submit(it.next()));
            --ntasks;
            int active = 1;

            for (;;) {
                Future<T> f = ecs.poll();
                if (f == null) {
                    if (ntasks > 0) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    }
                    else if (active == 0)
                        break;
                    else if (timed) {
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null)
                            throw new TimeoutException();
                        long now = System.nanoTime();
                        nanos -= now - lastTime;
                        lastTime = now;
                    }
                    else
                        f = ecs.take();
                }
                if (f != null) {
                    --active;
                    try {
                        return f.get();
                    } catch (ExecutionException eex) {
                        ee = eex;
                    } catch (RuntimeException rex) {
                        ee = new ExecutionException(rex);
                    }
                }
            }

            if (ee == null)
                ee = new ExecutionException();
            throw ee;

        } finally {
            for (Future<T> f : futures)
                f.cancel(true);
        }
    }

    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException {
        try {
            return doInvokeAny(tasks, false, 0);
        } catch (TimeoutException cannotHappen) {
            assert false;
            return null;
        }
    }

    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                           long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        return doInvokeAny(tasks, true, unit.toNanos(timeout));
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks) {
                RunnableFuture<T> f = newTaskFor(t);
                futures.add(f);
                execute(f);
            }
            for (Future<T> f : futures) {
                if (!f.isDone()) {
                    try {
                        f.get();
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    }
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (Future<T> f : futures)
                    f.cancel(true);
        }
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                         long timeout, TimeUnit unit)
        throws InterruptedException {
        if (tasks == null || unit == null)
            throw new NullPointerException();
        long nanos = unit.toNanos(timeout);
        List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
                futures.add(newTaskFor(t));

            long lastTime = System.nanoTime();

            // Interleave time checks and calls to execute in case
            // executor doesn't have any/much parallelism.
            Iterator<Future<T>> it = futures.iterator();
            while (it.hasNext()) {
                execute((Runnable)(it.next()));
                long now = System.nanoTime();
                nanos -= now - lastTime;
                lastTime = now;
                if (nanos <= 0)
                    return futures;
            }

            for (Future<T> f : futures) {
                if (!f.isDone()) {
                    if (nanos <= 0)
                        return futures;
                    try {
                        f.get(nanos, TimeUnit.NANOSECONDS);
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    } catch (TimeoutException toe) {
                        return futures;
                    }
                    long now = System.nanoTime();
                    nanos -= now - lastTime;
                    lastTime = now;
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (Future<T> f : futures)
                    f.cancel(true);
        }
    }

}

AbstractExecutorService是多少个抽象类,它达成了ExecutorService接口,而ExecutorService又是世襲了Executor接口,它们的基本关系如下:

  • Executor是三个顶层接口,在它当中只注脚了贰个方法execute(Runnable卡塔尔,重临值为void,参数为Runnable类型,用来实行传进去的任务的;
  • ExecutorService接口世袭了Executor接口,并宣称了部分办法:submit、invokeAll、invokeAny以至shutDown等;
  • 抽象类AbstractExecutorService完毕了Executor瑟维斯接口,基本落到实处了ExecutorService中评释的具备办法;
  • ThreadPoolExecutor世襲了类AbstractExecutorService,

在ThreadPoolExecutor类中有多少个非常关键的方法:

execute()
submit()
shutdown()
shutdownNow()
  • execute(卡塔尔(قطر‎方法其实是Executor中声称的诀窍,在ThreadPoolExecutor进行了现实的兑现,那一个措施是ThreadPoolExecutor的骨干措施,通过那一个艺术能够向线程池提交叁个职务,交由线程池去实施。
  • submit(卡塔尔(قطر‎方法是在ExecutorService中声称的主意,在AbstractExecutorService就已经有了现实的落实,在ThreadPoolExecutor中并不曾对其举行重写,这几个法子也是用来向线程池提交职务的,不过它和execute(卡塔尔(英语:State of Qatar)方法不一致,它能够回来义务试行的结果,去看submit(卡塔尔国方法的达成,会意识它实际依然调用的execute(卡塔尔(英语:State of Qatar)方法,只但是它利用了Future来获取任务推行结果。
  • shutdown(卡塔尔国和shutdownNow(卡塔尔(英语:State of Qatar)是用来关闭线程池的。

线程池族谱

  ThreadPoolExecutor的涉嫌图轻便如下。

澳门国际官方网站 1

澳门国际官方网站,  简要介绍部分Executor、ExecutorService、AbstractExectorService。

  Executor接口比较轻巧:

1 public interface Executor {
2     void execute(Runnable command);
3 }

  该接口唯有七个主意,即职务的举办。

  ExecutorService在Executor接口上,增多了拘留生命周期的方式、帮忙了Callable类型的天职、职分的施行措施。

澳门国际官方网站 2

  AbstractExecutorService是叁个抽象类,完结了ExecutorService的职务施行办法,增多newTaskFor方法作为钩子对外提供职分的打消通道,不过AbstractExecutorService并从未贯彻生命周期管理相关的艺术,而是将生命周期相关的操作丢给了子类。

澳门国际官方网站 3

正文

下面的线程池的例证中用到的ThreadPoolExecutor是JDK并发包提供的二个线程池服务,基于ThreadPoolExecutor能够相当轻便将三个Runnable接口的天职归入线程池中。

ThreadPoolExecutor提供了八个构造器,看源码能够发掘前多个布局器都是调用的第两个构造器实行的领头化学工业作:

public class ThreadPoolExecutor extends AbstractExecutorService {
   ...
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
}
...
}

 

2.解析线程池完毕原理

线程池奋见死不救的一生

构造器中各种参数的意思:

corePoolSize:主旨池的朗朗上口,那一个参数跟后边陈说的线程池的落到实处原理有超大的涉及。在开创了线程池后,默许情况下,线程池中并未其他线程,而是等待有职分赶来才创立线程去施行职责,除非调用了prestartAllCoreThreads(卡塔尔(英语:State of Qatar)也许prestartCoreThread(卡塔尔(قطر‎方法,从那2个点子的名字就能够看来,是预成立线程的情趣,即在尚未职务赶来此前就创办corePoolSize个线程只怕三个线程。暗中认可情形下,在创制了线程池后,线程池中的线程数为0,当有职分来之后,就能够创立贰个线程去实践任务,当线程池中的线程数目达到corePoolSize后,就能把达到的天职放到缓存队列在那之中;

maximumPoolSize:线程池最大线程数,那么些参数也是一个可怜重大的参数,它意味着在线程池中最多能创立多少个线程;

keepAliveTime:表示线程未有任务实行时最多维持多长期时辰会告生龙活虎段落。默许景况下,独有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起效果,直到线程池中的线程数不超过corePoolSize,即当线程池中的线程数大于corePoolSize时,假设三个线程空闲的时日到达keep阿里ve提姆e,则会告意气风发段落,直到线程池中的线程数不超越corePoolSize。然而朝气蓬勃旦调用了allowCoreThreadTimeOut(boolean卡塔尔(قطر‎方法,在线程池中的线程数不超过corePoolSize时,keep阿里veTime参数也会起成效,直到线程池中的线程数为0;

unit:参数keepAliveTime(线程池维护线程所允许的闲暇时间的单位),可选参数值有7种取值,在TimeUnit类中有7种静态属性:

TimeUnit.DAYS;               //天
TimeUnit.HOURS;             //小时
TimeUnit.MINUTES;           //分钟
TimeUnit.SECONDS;           //秒
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //纳秒

澳门网址网站导航大全,workQueue:一个围堵队列,用来储存等待推行的任务,那一个参数的选取也很要紧,会对线程池的运作进程产生至关心重视要影响,平常的话,这里的短路队列有以下几种选拔:

ArrayBlockingQueue;

LinkedBlockingQueue;

SynchronousQueue;

ArrayBlockingQueue和PriorityBlockingQueue使用超级少,日常选择LinkedBlockingQueue和Synchronous。线程池的排队战术与BlockingQueue有关。

threadFactory:线程工厂,重要用以成立线程;

handler:表示当拒却管理职务时的政策,有以下两种取值(暗中认可ThreadPoolExecutor.AbortPolicy):

ThreadPoolExecutor.AbortPolicy:放任职分并抛出RejectedExecutionException卓殊。

ThreadPoolExecutor.DiscardPolicy:也是撤废职务,可是不抛出十二分。

ThreadPoolExecutor.DiscardOldestPolicy:甩掉队列最前方的职务,然后重新尝试进行职务(重复此进程)。

ThreadPoolExecutor.CallerRunsPolicy:由调用线程管理该职务,线程调用运转该职务的execute 本人。此政策提供轻易的反映调控机制,能够减缓新任务的交由速度。

 

从下面给出的ThreadPoolExecutor类的代码能够清楚,ThreadPoolExecutor世襲了AbstractExecutor瑟维斯,AbstractExecutorService是叁个抽象类,它完毕了ExecutorService接口。而ExecutorService又是三番一回了Executor接口。(以上实际代码能够自动翻阅JDK源码,因为太多就不黄金时代后生可畏粘贴)

Executor是三个顶层类,里面只评释了三个execute(卡塔尔国方法,重返值为void,参数为Runable类型,成效正是施行传进去的职务的。

 

在ThreadPoolExecutor类中有多少个要命关键的艺术:

execute()

submit()

shutdown()

shutdownNow()

execute(卡塔尔(英语:State of Qatar)方法其实是Executor中扬言的法子,在ThreadPoolExecutor举行了切实可行的实现,这一个主意是ThreadPoolExecutor的中央措施,通过这些措施能够向线程池提交一个职责,交由线程池去试行。

submit(卡塔尔国方法是在ExecutorService中扬言的法子,在AbstractExecutorService就已经有了切实可行的落到实处,在ThreadPoolExecutor中并不曾对其张开重写,这一个方法也是用来向线程池提交职责的,不过它和execute(卡塔尔(قطر‎方法不一致,它亦可回到职务执行的结果,去看submit(卡塔尔(قطر‎方法的贯彻,会意识它事实上依然调用的execute(卡塔尔(英语:State of Qatar)方法,只可是它使用了Future来获取任务执行结果。

shutdown(卡塔尔国和shutdownNow(卡塔尔国是用来关闭线程池的;调用shutdown(卡塔尔(英语:State of Qatar)方法,线程池处于SHUTDOWN状态,那时候线程池无法选取新的天职,它会等待全体职责实施完结;调用shutdownNow(卡塔尔国方法,线程池处于STOP状态,这个时候线程池不能够选取新的职分,何况回去尝试终止正在推行的天职,重返尚未进行的职分。

 

线程池状态

成员变量ctl是个Integer的原子变量用来记录线程池状态和线程池线程个数,此中Integer类型是33个人二进制标示,个中高3位用来代表线程池状态,后面二十几个人用来记录线程池线程个数。

//用来标记线程池状态(高3位),线程个数(低29位)
//默认是RUNNING状态,线程个数为0
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

//线程个数掩码位数
private static final int COUNT_BITS = Integer.SIZE - 3;

//线程最大个数(低29位)00011111111111111111111111111111
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

//(高3位):11100000000000000000000000000000
private static final int RUNNING    = -1 << COUNT_BITS;

//(高3位):00000000000000000000000000000000
private static final int SHUTDOWN   =  0 << COUNT_BITS;

//(高3位):00100000000000000000000000000000
private static final int STOP       =  1 << COUNT_BITS;

//(高3位):01000000000000000000000000000000
private static final int TIDYING    =  2 << COUNT_BITS;

//(高3位):01100000000000000000000000000000
private static final int TERMINATED =  3 << COUNT_BITS;

// 获取高三位 运行状态
private static int runStateOf(int c)     { return c & ~CAPACITY; }

//获取低29位 线程个数
private static int workerCountOf(int c)  { return c & CAPACITY; }

//计算ctl新值,线程状态 与 线程个数
private static int ctlOf(int rs, int wc) { return rs | wc; }

线程池状态含义:

  • RUNNING:选用新职责而且管理堵塞队列里的职务
  • SHUTDOWN:拒却新任务不过管理梗塞队列里的职务
  • STOP:屏绝新职分而且扬弃堵塞队列里的任务相同的时候会搁浅正在管理的天职
  • TIDYING:全数任务都实践完(包括梗塞队列之中职务)当前线程池活动线程为0,就要调用terminated方法
  • TERMINATED:终止情状。terminated方法调用实现之后的情景

     *   RUNNING:  Accept new tasks and process queued tasks
     *   SHUTDOWN: Don't accept new tasks, but process queued tasks
     *   STOP:  Don't accept new tasks, don't process queued tasks,and interrupt in-progress tasks
     *   TIDYING:  All tasks have terminated, workerCount is zero, the thread transitioning to state TIDYING, will run the terminated() hook method
     *   TERMINATED: terminated() has completed

线程池状态调换:

RUNNING -> SHUTDOWN
显式调用shutdown(卡塔尔方法,或然隐式调用了finalize(卡塔尔,它里面调用了shutdown()方法。

RUNNING or SHUTDOWN)-> STOP
显式 shutdownNow()方法

SHUTDOWN -> TIDYING
当线程池和职务队列都为空的时候

STOP -> TIDYING
当线程池为空的时候

TIDYING -> TERMINATED
当 terminated(卡塔尔(英语:State of Qatar) hook 方法实行到位时候

本文由澳门网络娱乐游戏平台发布于编程,转载请注明出处:澳门网址网站导航大全ThreadPoolExecutor 学习笔记

相关阅读