①什么是线程池?
线程池是对所有线程进行统一的管理和控制,从而提高系统的运行效率。当我们要使用线程的时候可以直接从线程池中拿,用完也不用自己去销毁,省去创建和销毁的时间,提升系统的响应时间。
②线程池的七大核心参数
①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()*/@Overridepublic 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*/@Overridepublic Integer call() throws Exception {System.out.println("线程的名称为: "+Thread.currentThread().getName());return 2;}
}
⑥线程池的四种拒绝策略
①AbortPolicy(我满了还给我,我直接报错):直接抛出异常,阻止系统正常运行。(默认策略,但不推荐)
②CallerRunsPolicy(我满了,你自己运行去):直接将任务交给调用者的线程去执行,会导致TPS会增高。
③DiscardOldestpolicy(我喜新厌旧):丢弃最老的请求,即马上要被执行的任务。
④DiscardPolicy(我不要,你硬塞,我偷偷丢掉摆烂):不予任何处理