为什么要用线程池?
线程是不是越多越好?
- 线程在java中是一个对象,更是操作系统的资源,线程创建、销毁需要时间。如果创建时间+小会时间>执行任务时间就很不合算。
- java对象占用堆内存,操作系统线程占用系统内存,根据jvm规范,一个线程默认最大栈大小1M,这个栈空间是需要从系统内存中分配的。线程过多,会消耗很多的内存。
- 操作系统需要频繁切换线程上下文(每个线都想被运行),影响性能。
线程池的推出,就是为了方便边的控制线程数量。
线程池
线程池基本概念
线程池包括以下四个基本组成部分:
- 线程池管理器:用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;
- 工作线程:线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
- 任务接口:每个任务必须实现的借口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
- 任务队列:用于存放没有处理的任务。提供一种缓冲机制。
线程池接口定义和实现类
可以认为ScheduledThreadPoolExector是最丰富的实现类。
ExecutorService
public interface ExecutorService extends Executor {
/**
* 优雅关闭线程池,之前提交的任务将被执行,但是不会接受新的任务。
*/
void shutdown();
/**
* 尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行任务的列表。
*/
List<Runnable> shutdownNow();
/**
* 如果此线程池已关闭,则返回true.
*/
boolean isShutdown();
/**
* 如果关闭后的所有任务都已完成,则返回true
*/
boolean isTerminated();
/**
* 监测ExecutorService是否已经关闭,直到所有任务完成执行,或超时发生,或当前线程被中断。
*/
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
/**
* 提交一个用于执行的Callable返回任务,并返回一个Future,用于获取Callable执行结果。
*/
<T> Future<T> submit(Callable<T> task);
/**
* 提交可运行任务以执行,并返回Future,执行结果为传入的result
*/
<T> Future<T> submit(Runnable task, T result);
/**
* 提交可运行任务以执行,并返回Future对象,执行结果为null
*/
Future<?> submit(Runnable task);
/**
* 执行给定的任务集合,执行完毕后,则返回结果。
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
/**
* 执行给定的任务集合,执行完毕或者超时后,则返回结果,其他任务终止。
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
/**
* 执行给定的任务,任意一个执行成功则返回结果,其他任务终止。
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
/**
* 执行给定的任务,任意一个执行成功或者超时后,则返回结果,其他任务终止
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}
ScheduledExecutorService
public interface ScheduledExecutorService extends ExecutorService {
/**
* 创建并执行一个一次性任务,过了延迟时间就会被执行
*/
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
/**
* 创建并执行一个一次性任务,过了延迟时间就会被执行
*/
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
/**
* 创建并执行一个周期性任务,过了给定的初始化延迟时间,会第一次被执行。执行过程中发生了异常,那么任务停止
* 一次任务执行时