线程池源码解读到此结束(其实总觉得少了点什么,就是找不到),本文简单总结一下前面的过程和一些用法。1线程池流程图通过两篇文章,每个部分可以单独理解,但整体流程并没有串联起来。让我们看一下整体流程图。2综合示例接下来我们用一个综合示例来分析一些Review知识点2.1自定义ThreadPoolExecutor首先自定义ThreadPoolExecutor,然后重写beforeExecute()和afterExecute()方法publicclassMyThreadPoolExecutorextendsThreadPoolExecutor{//省略父类的构造函数4@OverrideprotectedvoidbeforeExecute(Threadt,Runnabler){System.out.println("【执行前】"+r.toString());}@OverrideprotectedvoidafterExecute(Runnabler,Throwablet){System.out.println(r.toString()+"【执行后】");}}注意这里省略了构造函数,一般IDE会提示错误。至少需要实现一个2.2自定义的RejectedExecutionHandler自定义拒绝策略。现在没有具体要求,好听就是自定义的拒绝策略,不好听简直难以实现。publicclassMyRejectedExecutionHandlerimplementsRejectedExecutionHandler{@OverridepublicvoidrejectedExecution(Runnabler,ThreadPoolExecutorexecutor){System.out.println("任务被拒绝");}}甚至没有对任务做任何处理,知识只有控制台输出一句话。2.3监听线程池状态的线程开头也普及了线程池中的一些相关参数。通过下面的监控线程,可以更直观的了解这些参数。公共类MonitorThread实现Runnable{privateThreadPoolExecutor执行器;publicMonitorThread(ThreadPoolExecutorexecutor){this.executor=executor;}私有布尔监视器=true;publicvoidstopMonitor(){monitor=false;}@Overridepublicvoidrun(){while(monitor){System.out.println(String.format("[monitor][%d/%d]Active:%d,Completed:%d,Task:%d,isShutdown:%s,isTerminated:%s,rejectedExecutionHandler:%s",this.executor.getPoolSize(),this.executor.getCorePoolSize(),this.executor.getActiveCount(),this.executor.getCompletedTaskCount(),这个。executor.getTaskCount(),this.executor.isShutdown(),this.executor.isTerminated(),this.executor.getRejectedExecutionHandler()));尝试{Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}}}}2.4自定义线程估计这么久了,小伙伴们都忘记了第一次线程体验开始时创建的类。在这里我重复publicclassMyThreadimplementsRunnable{@Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName()+"processing");过程();System.out.println(Thread.currentThread().getName()+"结束");}privatevoidprocess(){try{Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}}@OverridepublicStringtoString(){returnString.format("MyThread{%s}",Thread.currentThread().getName());}}虽然这是一个线程,但实际上在线程池中算是一个任务。线程池会创建一个核心线程来执行这个任务(逻辑就是这个线程中的run()方法)。2.5测试类有了上面,我们就可以开始我们的测试了(3)、newMyRejectedExecutionHandler());MonitorThreadmonitorThread=newMonitorThread(executor);//启动监听线程newThread(monitorThread).start();for(inti=0;i<10;i++){//开始工作线程executor.execute(newMyThread());}Thread.sleep(12000);执行器.shutdown();线程.睡眠(3000);monitorThread.stopMonitor();在整体运行结果的gif动画中,可以看到有前后端执行策略,也有拒绝策略,以及线程池的相关状态等。接下来仔细看一下状态线程池通过截图。线程池的状态如下。队列长度+最大线程数。如果仔细看过源码分析,应该就知道原因了。这里先说一下队列的长度。在execute中查看代码中的最大线程数,addWorker简单来说就是一个wc(工作线程数),当达到最大PoolSize时,此时任务队列也很忙,而这是最大的任务可以被容忍。结束语java多线程中的线程池告一段落了。这些理论相对简单。线程池的复杂性涉及底层操作系统。基本上不可能预测操作系统将运行哪个线程。写这些理论知识,就是在我们可控的水平上,尽可能去理解它。用下图做一个总结,你理想中的线程池vs真正的线程池
