线程池
线程池是一个线程缓存,线程是稀缺资源,如果被无限制的创建,不仅仅会消耗系统资源,还会降低系统的稳定性。
什么时候使用线程池
- 单个任务处理时间比较短
- 需要处理的任务数量很大
线程池的优势
- 重用存在的线程,减少线程创建、消亡的开销,提高性能
- 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
- 提高线程的可管理性。线程时稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统稳定性,使用线程池可以进行统一的分配,调优和监控。
线程的实现方法
Runnable,Thread,Callable
//实现Runnable接口的类将被Thread执行,表示一个基本的任务
public interface Runnable {
// run方法就是它所有的内容,就是实际执行的任务
public abstract void run();
}
//Callable同样是任务,与Runnable接口的区别在于它接收泛型,同时它执行 任务后带有返回内容
public interface Callable<V> {
// 相对于run方法的带有返回值的call方法
V call() throws Exception;
}
Executor框架
Executor接口时线程池框架中最基础的部分,定义了一个用于执行Runnable的execute方法。
从图中可以看出Executor下有一个重要子接口ExecutorService,其中定义了线程池的具体行为。
- execute:履行Ruannable类型的任务
- sumit:用来提交Callable或者Runnable任务,并返回代表此任务的Future对象。
- shutdown():在完成已提交的任务后封闭办事,不再接管新任务
- shutdownNow():停止所有正在履行的任务并封闭办事。
- is Terminated():测试是否所有任务都履行完毕了
- isshutdown():测试是否该ExecutorService已被关闭
线程池重点属性
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
ctl是对线程池的运行状态和线程池中有效线程的数量进行控制的一个字段,它包含两部分信息:线程池的运行状态和线程池内有效线程的数量,这里可以看到,使用了Integer类型来保存,高三位保存运行状态,低29位保存有效线程的数量。COUNT_BITS就是29,CAPACITY就是1左移29位减1(29个1),这个常量表示workerCount的上限值,大约是5亿。
ctl相关方法
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
runStateOf:获取运行状态
workerCountOf:获取活动线程数
ctlOf:获取运行状态和活动线程数的值
线程池5种状态
private static final int RUNNING = -1 << COUNT_BITS;//高三位为111
private static final int SHUTDOWN = 0 << COUNT_BITS;//高三位为000
private static final int STOP = 1 << COUNT_BITS;//高三位为001
private static final int TIDYING = 2 << COUNT_BITS;//高三位为010
private static final int TERMINATED = 3 << COUNT_BITS;//高三位位011
- RUNNING:线程池处在Running状态,能够接受新任务,以及对已添加的任务进行处理。线程池的初始化状态就是RUNNing,线程池一旦被创建,就处于RUNNING状态,并且线程池种的任务数为10.
- SHUTDOWN:线程池处在shutdown状态时,不再接受新任务,但是能处理已添加的任务。调用线程池的shutdown()接口时,线程池由running-》shutdown。
- stop:线程处在stop状态,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。调用线程池的SHUTDOWNNOW()接口时,线程池由(RUNNING or SHUTDOWN )-》stop;
- tidying:当所有任务中止时,ctr记录的任务数量为0,线程池会变为tidying状态。当线程池变为tidying时,会执行钩子函数teminated()。terminated()在ThreadPoolExecutor中是空的,若用户想在线程池变为TIDYING时,进行相应的处理,可以通过重载Terminated()函数来实现。当线程池在shutdown状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由shutdown-》tidying。当线程池在stop状态下,线程池中执行的任务为空时,就会由stop-》tidying。
- terminated:线程池彻底终止,就会变成terminated状态。线程池处在tidying时,执行完terminated()后,就会由tidying-》terminated。
线程池的具体实现
ThreadPoolExecutor 默认线程池
ScheduledThreadPoolExecutor定时线程池