线程池-2种创建方式

2020-08-10  本文已影响0人  rock_fish

一、通过Executors工厂来创建线程池(慎用)

Methods that create and return an ExecutorService set up with commonly useful configuration settings.
Methods that create and return a ScheduledExecutorService set up with commonly useful configuration settings.
Methods that create and return a "wrapped" ExecutorService, that disables reconfiguration by making implementation-specific methods inaccessible.
Methods that create and return a ThreadFactory that sets newly created threads to a known state.
Methods that create and return a Callable out of other closure-like forms, so they can be used in execution methods requiring Callable.

具体的工厂方法如下:

java.util.concurrent.Executors#newFixedThreadPool(int)
java.util.concurrent.Executors#newWorkStealingPool(int)
java.util.concurrent.Executors#newWorkStealingPool()
java.util.concurrent.Executors#newFixedThreadPool(int, java.util.concurrent.ThreadFactory)
java.util.concurrent.Executors#newSingleThreadExecutor()
java.util.concurrent.Executors#newSingleThreadExecutor(java.util.concurrent.ThreadFactory)
java.util.concurrent.Executors#newCachedThreadPool()
java.util.concurrent.Executors#newCachedThreadPool(java.util.concurrent.ThreadFactory)
java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
java.util.concurrent.Executors#newSingleThreadScheduledExecutor(java.util.concurrent.ThreadFactory)
java.util.concurrent.Executors#newScheduledThreadPool(int)
java.util.concurrent.Executors#newScheduledThreadPool(int, java.util.concurrent.ThreadFactory)
java.util.concurrent.Executors#unconfigurableExecutorService
java.util.concurrent.Executors#unconfigurableScheduledExecutorService

大体分为以下4类:

1、 newSingleThreadExecutor

创建一个单线程的线程池,保证所有任务按照提交顺序执行
适用:一个任务一个任务执行的场景

2、newFixedThreadPool

创建一个固定大小的线程池,因为采用无界的阻塞队列,所以实际线程数量永远不会变化
适用:执行长期的任务,性能好很多

3、newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
适用:执行很多短期异步的小程序或者负载较轻的服务器

4、 newScheduledThreadPool

创建一个可定期或者延时执行任务的定长线程池,支持定时及周期性任务执行。
适用:周期性执行任务的场景

image.png

通常不使用这些工厂方法来创建线程池,原因是这些方法所使用的一些参数可能会产生严重的问题,在掌握下边的线程池方法参数的作用的前提下,去评估Executors所提供的方法是否可用。

二、 手动 new ThreadPollExecutor(xxx)

显式的通过构造方法来创建线程池。

image.png
    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.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
1、corePoolSize(线程池基本大小):
2、maximumPoolSize(线程池最大大小)
3、keepAliveTime、TimeUnit unit(线程存活保持时间)
4、workQueue(任务队列)
5、threadFactory(线程工厂)
6、handler(线程饱和策略)

当线程池和队列都满了,再来任务会执行此策略。

线程池任务执行流程:

  1. 当线程池小于corePoolSize时,新提交任务将创建一个新线程来执行任务,即使此时线程池中存在空闲线程。
  2. 当线程池线程数量达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
  3. 当workQueue已满,且maximumPoolSize>corePoolSize时,对于新提交任务,线程池会创建新的线程来执行
  4. 当线程数超过maximumPoolSize时,且无空闲线程时,新提交任务由RejectedExecutionHandler处理
  5. 当线程池中线程数超过corePoolSize,若线程空闲时间达到keepAliveTime时,将被回收。
  6. 当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭

注意


java四种线程池的使用
Java线程池详解

上一篇下一篇

猜你喜欢

热点阅读