①什么是线程池?
线程池是对所有线程进行统一的管理和控制,从而提高系统的运行效率。当我们要使用线程的时候可以直接从线程池中拿,用完也不用自己去销毁,省去创建和销毁的时间,提升系统的响应时间。
②线程池的七大核心参数
①corePoolSize,核心线程数。
②maximumPoolSize,最大线程数。
③keepAliveTime,空闲线程存活时间。
④unit,时间单位。
⑤workQueue,等待队列。
⑥ThreadFactory,线程工厂,用于创建线程。
⑦handler:拒绝策略。
③线程池状态
①Running运行状态:创建线程池或者添加任务之后,线程池则处于运行状态。
②Shutdown关闭状态:当执行shutdown()命令后,线程池就会进入关闭状态,但是正在执行的任务以及在任务队列中的任务并不会终止,只是停止接收新的任务。
③Stop停止状态:当执行shutdownNow()命令后,线程池就会进入关闭状态,此时不管是正在执行的任务还是在任务队列中的任务都会被终止,并且会返回一个未被执行的任务列表
④Tidying整理状态:所有任务都已经执行完了,进入整理状态
⑤Terminated终止状态:线程池彻底关闭。
④线程池的工作流程
①接收到任务,先去检查核心线程数是否全部用完了,如果没用完,就直接执行任务。
②当发现核心线程数用完了,就去检查任务队列是否满了,如果没满就把任务放进队列中
③当任务队列也满了的话,则去检查最大线程数是否还有空闲,如果还没达到最大线程数,则会创建一个非核心线程去执行任务。
④当最大核心线程数也不够了的话,就会通过拒绝策略/饱和策略去拒绝任务。
⑤线程池的创建方式
public class ExecutorTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建线程池----->缓冲线程池
ExecutorService es = Executors.newCachedThreadPool();
//提交任务
for (int i = 0; i < 10; i++) {
es.submit(new MtRunnable());
}
//创建线程池----->指定线程数量线程池
ExecutorService es2 = Executors.newFixedThreadPool(3);
//提交任务
for (int i = 0; i < 10; i++) {
es2.submit(new MtRunnable());
}
//创建线程池----->创建单线程线程池
ExecutorService es3 = Executors.newSingleThreadExecutor();
//提交任务
for (int i = 0; i < 10; i++) {
Future<Integer> submit = es3.submit(new MtRunnable02());
System.out.println(submit.isDone());
Thread.sleep(2000);
System.out.println("submit = " + submit.get());
System.out.println(submit.isDone());
}
//创建线程池----->创建定长线程池,带有定时任务
ExecutorService es4 = Executors.newScheduledThreadPool(3);
//提交任务
for (int i = 0; i < 10; i++) {
es4.submit(new MtRunnable());
List<Runnable> runnables = es4.shutdownNow();
}
//创建定时线程池
ScheduledThreadPoolExecutor es5 = new ScheduledThreadPoolExecutor(3);
for (int i = 0; i < 10; i++) {
es5.schedule(new MtRunnable(),5, TimeUnit.SECONDS);
}
}
}
class MtRunnable implements Runnable{
/**
* @see Thread#run()
*/
@Override
public void run() {
System.out.println("线程的名称为: "+Thread.currentThread().getName());
}
}
class MtRunnable02 implements Callable<Integer>{
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
@Override
public Integer call() throws Exception {
System.out.println("线程的名称为: "+Thread.currentThread().getName());
return 2;
}
}
⑥线程池的四种拒绝策略
①AbortPolicy(我满了还给我,我直接报错):直接抛出异常,阻止系统正常运行。(默认策略,但不推荐)
②CallerRunsPolicy(我满了,你自己运行去):直接将任务交给调用者的线程去执行,会导致TPS会增高。
③DiscardOldestpolicy(我喜新厌旧):丢弃最老的请求,即马上要被执行的任务。
④DiscardPolicy(我不要,你硬塞,我偷偷丢掉摆烂):不予任何处理