欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java ExecutorService 的简单了解

程序员文章站 2024-03-18 11:26:10
...

一、ExecutorService 是Java提供的线程池,是Executor直接的扩展接口,也是最常用的线程池接口。

二、ExecutorService 的创建方式

1. 通过以下方法可以创建线程池:

ExecutorService executorService = new ThreadPoolExecutor(
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler)

ThreadPoolExecutor 方法中各参数介绍:

  1. corePoolSize: 核心线程数,一旦创建将不会再释放。如果创建的线程数还没有达到指定的核心线程数量,将会继续创建新的核心线程,直到达到最大核心线程数后,核心线程数将不在增加;如果没有空闲的核心线程,同时又未达到最大线程数,则将继续创建非核心线程;如果核心线程数等于最大线程数,则当核心线程都处于**状态时,任务将被挂起,等待空闲线程来执行。
  2. maximumPoolSize: 最大线程数,允许创建的最大线程数量。如果最大线程数等于核心线程数,则无法创建非核心线程;如果非核心线程处于空闲时,超过设置的空闲时间,则将被回收,释放占用的资源。
  3. keepAliveTime: 也就是当线程空闲时,所允许保存的最大时间,超过这个时间,线程将被释放销毁,但只针对于非核心线程
  4. unit: 时间单位,TimeUnit.SECONDS等。
  5. wordQueue: 任务队列,存储暂时无法执行的任务,等待空闲线程来执行任务。
  6. threadFactory: 线程工程,用于创建线程。
  7. handler: 当线程边界和队列容量已经达到最大时,用于处理阻塞时的程序。

三、Java ExecutorService 可快捷创建的四种线程池

1. 可缓存的线程池:newCachedThreadPool

创建方法:

ExecutorService cacheThreadPool = Executors.newCachedThreadPool();

Executors.newCachedThreadPool() 的具体创建方法:

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

创建的线程池,核心线程数是0,最大线程数为Interge的最大值,空闲线程存活时间是1分钟,创建都是非核心线程。

这种方式创建的线程池比较适合生命周期短的任务 。如果有大量耗时的任务,那么不适合创建这样的线程池。

2.  固定线程数的线程池:newFixedThreadPool 

创建方式:

int nThreads = 3;
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(nThreads);

Executors.newFixedThreadPool(nThreads) 的具体创建方法:

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

这种方式创建固定数量的可复用的线程数,来执行任务。当线程数达到最大核心线程数,则加入队列等待有空闲线程时再执行。

3. 固定线程数,支持定时、周期性执行任务的线程池:newScheduledThreadPool 

创建方式:

int corePoolSize = 3;
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(corePoolSize);

Executors.newScheduledThreadPool(corePoolSize) 的具体创建方式:

// Executors.java
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }

// ScheduledThreadPoolExecutor.java
// 继承关系:class ScheduledThreadPoolExecutor extends ThreadPoolExecutor
public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

3.1 创建并执行一个延时执行的任务

scheduledThreadPool.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("delay 3 seconds");
            }
        }, 3, TimeUnit.SECONDS);

3.2 创建并执行一个延时后并定期执行的任务

scheduledThreadPoolRate.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("delay 1 second, and execute every 3 seconds");
            }
        }, 1, 3, TimeUnit.SECONDS);

4. 单线程池:newSingleThreadExecutor

创建方式:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

Executors.newSingleThreadExecutor() 的具体创建方式:

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

只用一个线程来执行任务,保证任务按FIFO( First Input First Output,简单说就是指先进先出)顺序一个个执行。

 

【参考】

1. ExecutorService详解

转载于:https://my.oschina.net/zhishengji/blog/3008830