java 线程池对象ThreadPoolExecutor

ThreadPoolExecutor 介绍:

  java 提供的线程池类;

ThreadPoolExecutor 作用:

  两个作用:

  1,用于分离执行任务和当前线程;

  2,主要设计初衷:重复利用Thread 对象;

ThreadPoolExecutor 使用:

   实例化:

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

  这是ThreadPoolExecutor的构造方法之一,传入参数最少,以下是参数说明:

  corePoolSize  : 设置线程池的线程核心数量;该参数作用:当向线程池中添加的任务数量小于核心数量时,线程池将优先创建新的线程,而不是重用之前已存在的线程(不管该线程可用与否);

  源码佐证,ThreadPoolExecutor 的 execute(Runnable) 方法中有源码如下:

  maximumPoolSize : 设置线程池可创建最大线程数量;该参数作用:用于限制线程池无限制的创建线程;

  源码佐证,ThreadPoolExecutor 的 addWorker(Runnable ,boolean) 方法中有源码如下:

  keepAliveTime  : 设置线程池被创建线程的存活时间;

  源码佐证,ThreadPoolExecutor 的 getTask()方法中有源码如下;源码说明:创建的线程将从任务队列中获取一个新的任务,在keepAliveTime时间之后如果还未获取到任务,将关闭该线程;

 

  unit :设置线程池线程存活时间的时间单位;

  workQueue :设置线程池用于存放任务的队列;

  注意:ThreadPoolExecutor线程池是否创建新的线程不仅仅依赖于corePoolSize变量,还依赖于任务队列的offer(E) 方法所返回的值;比如:想要创建一个cache线程池,就依赖于一个特殊的任务队列:SynchronousQueue<E>;

   源码佐证,ThreadPoolExecutor 的execute(Runnable) 方法中有源码如下:

  示例: 创建固定线程池 和 cache线程池;

  固定线程池,将corePoolSize 和 maximumPoolSize 设置相同即可,在Executors.newFixedThreadPool(10)有源码示例:

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

  cacahe线程池,需要传入特殊的BlockingQueue对象,该对象需要在offer是返回false,并能够在poll方法中监听到offer进入的任务;java 提供了一个SynchronousQueue类,该类就是这样一个对象;在Executors.newCachedThreadPool()方法中,有源码示例:

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

  常用方法提示:

    void execute(Runnable command) : 任务提交方法;线程池将顺序执行所提交的所有方法;

    void shutdown() : 停止后续任务提交,但执行完当前线程池中所有任务;该方法的作用:线程池将中断当前所有空闲的线程,但不保证一定中断(可查看Thread的interrupt方法);那么工作中的线程将继续工作,直到完成;

    源码:

    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(SHUTDOWN);
            interruptIdleWorkers();    、//中断所有空闲的线程
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }

    List<Runnable> shutdownNow() : 立即终止线程池;该方法的作用:线程池将中断所有创建的线程,但不保存一定中断;线程池将所有剩余的任务从任务队列中移除,不在执行,并保存在一个List中返回给用于;

    方法源码:

 public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(STOP);
            interruptWorkers();
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }

ThreadPoolExecutor 任务执行流程图:

  

ThreadPoolExecutor 使用注意点说明:

  清晰需要使用的是那种类型的线程池,在实例化ThreadPoolExecutor时,传入的参数不同创建出来的线程池也将不同;尤其注意传入BlockingQueue参数,如果需要使用cache线程池,请确保BlockingQueue的offer方法反回false;可以参见SynchronousQueue类;

猜你喜欢

转载自www.cnblogs.com/loveyoumi/p/9578251.html