# 线程池

Executors.newCachedThreadPool()

创建一个可缓存的线程池,线程池的初始大小是0,最大为2147483647。调用execute()加入的新任务会重用之前的线程(空闲的话),如果没有可用的线程会创建一个新的线程并加入到线程池中,空闲线程最大存活时间是60秒。

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
    executorService.execute(() -> {
        System.out.println("ThreadName: " + Thread.currentThread().getName());
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
}
executorService.shutdown();

Executors.newFixedThreadPool(int nThreads)

创建一个固定大小的线程池,线程池的初始大小和最大值相同,超出的任务会放入队列中等待。

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
    executorService.execute(() -> {
        System.out.println("ThreadName: " + Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
}
executorService.shutdown();

Executors.newScheduledThreadPool(int corePoolSize)

创建一个固定大小的线程池,线程池的初始大小和最大值相同,超出的任务会放入队列中等待,支持定时及周期性任务执行。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
}
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
for (int i = 0; i < 10; i++) {
    scheduledExecutorService.schedule(() -> {
        System.out.println("ThreadName: " + Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, 2, TimeUnit.SECONDS);
}
scheduledExecutorService.shutdown();

Executors.newSingleThreadExecutor()

创建一个大小为1的线程池,所有的任务会按照加入的顺序依次执行。

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService(
        new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())
    );
}
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
    executorService.execute(() -> {
        System.out.println("ThreadName: " + Thread.currentThread().getName());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
}
executorService.shutdown();

Executors.newSingleThreadScheduledExecutor()

创建一个大小为1的线程池,所有的任务会按照加入的顺序依次执行,支持定时及周期性任务执行。

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
}
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
for (int i = 0; i < 10; i++) {
    scheduledExecutorService.schedule(() -> {
        System.out.println("ThreadName: " + Thread.currentThread().getName());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, 2, TimeUnit.SECONDS);
}
scheduledExecutorService.shutdown();

ExecutorService.shutdown()和ExecutorService.shutdownNow()

关闭线程池,shutdown()仅将线程池标记为SHUTWDOWN状态,而shutdownNow()会立刻停止执行任务并抛弃队列里尚未执行的任务,并将这些任务进行返回。

  • RUNNING 运行状态,执行队列里的任务且能接受新任务
  • SHUTDOWN 指调用了 shutdown() 方法,不再接受新任务了,但是队列里的任务继续执行完毕
  • STOP 指调用了 shutdownNow() 方法,不再接受新任务,同时抛弃阻塞队列里的所有任务并中断所有正在执行任务
  • TIDYING 所有任务都执行完毕,在调用 shutdown()/shutdownNow() 中都会尝试更新为这个状态
  • TERMINATED 终止状态,当执行 terminated() 后会更新为这个状态

调用shutdownNow()后,如果此时有任务正在执行,会进行一次中断操作,此时对应的线程报InterruptedException异常。

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;
}

ExecutorService.awaitTermination(long timeout, TimeUnit unit)

查看线程池状态,这个方法接收两个参数,超时时间和时间单位。它会阻塞并在超时后检测线程池是否关闭,关闭返回true否则返回false,如果在超时之前线程池提前关闭会立刻返回true。该方法仅检测线程池状态不会关闭线程池,通常和shutdown()一起使用。

executorService.shutdown();
while (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
    System.out.println("Thread Running ...");
}
System.out.println("Thread Terminated");

ThreadPoolExecutor.execute(Runnable command)

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    int c = ctl.get();
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
        c = ctl.get();
    }
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }
    else if (!addWorker(command, false))
        reject(command);
}