腾讯网站安全检测,ip地址做网站,福州定制网站开发制作,wordpress导入页面摘要 本文介绍了线程池基本概念、线程及线程池状态、java中线程池提交task后执行流程、Executors线程池工具类、最后介绍在springboot框架下使用线程池和定时线程池#xff0c;以及task取消 线程池基本
背景
线程池 线程池是一种多线程处理形式#xff0c;处理过程中将任务…摘要 本文介绍了线程池基本概念、线程及线程池状态、java中线程池提交task后执行流程、Executors线程池工具类、最后介绍在springboot框架下使用线程池和定时线程池以及task取消 线程池基本
背景
线程池 线程池是一种多线程处理形式处理过程中将任务添加到队列然后在创建线程后自动启动这些任务 线程池优势 降低执行task重复创建销毁线程的消耗提高执行task响应速度。切换到task时无需创建线程直接将task“挂”到线程执行 线程状态 线程共有6个状态分别是new、runnable、waiting、time_waiting、blocked、terminal。其中runnable状态包括running、ready。且runnable和waiting、time_waiting、blocked、terminal之间切换。 new 线程实例化初始状态 RUNNABLE(running、ready) running正在运行 readyrunning状态线程占用cpu时间片完主动调用yield后状态。 yield()向调度程序提示当前线程愿意放弃cpu的使用调度程序可以忽略此提示。很少使用可用于调试它可能有助于重现由于竞争条件而产生的错误。 waiting 等待状态例如调用wait、join、park方法线程等待 time_waiting 限时等待例如调用sleep(time)wait(time)join(time)parkNanos()parkUntil(thread) blocked 阻塞状态例如等待锁或等待进入synchronized块 terminal 线程终止 线程池状态
RUNNING 可接收新提交的任务可处理队列中任务。 SHUTDOWN 不再接收新提交的任务但是可处理队列中的任务。 STOP 不再接收新提交的任务且不再处理队列中的任务。 TIDYING 所有任务已经被终结工作线程数为0该状态会执行钩子函数terminated() TERMINATED 已执行完毕terminated()方法。 状态转换 RUNNING - SHUTDOWN调用shutdown()方法后。 (RUNNING or SHUTDOWN) - STOP调用shutdownNow()方法后。 SHUTDOWN - TIDYING当队列中任务为空线程池中任务为空。 TIDYING - TERMINATEDterminated()钩子方法执行完毕之后。 Java线程池实践
ThreadPool参数
corePoolSizemaximumPoolSizeworkQueuekeepAliveTimeTimeUnitthreadFactoryRejectedExecutionHandler
核心线程数 corePoolSize线程池中存活线程数量除非allowCoreThreadTimeOuttrue时会被kill 最大线程数 maximumPoolSize线程池允许最大线程数达到keepAliveTime后会被kill 等待时间和单位 keepAliveTime多于核心线程之外的线程超过该时间的线程会被kill TimeUnitkeepAliveTime时间单位 阻塞队列 workQueue保存未执行的Runnable 的task 线程工厂 threadFactory创建线程的工厂类默认Executors.defaultThreadFactory() 拒绝策略 RejectedExecutionHandler因队列满、且超过最maxThreadPool限制的task处理策略 AbortPolicy拒绝task抛出RejectedExecutionException 。是ThreadPoolExecutor和ScheduledThreadPoolExecutor的默认拒绝策略DiscardPolicy丢弃task无异常DiscardOldestPolicy丢弃未处理的最old的task无异常CallerRunsPolicy拒绝task抛回给提交task的线程执行 static volatile int count 0;public static void main(String[]args){
//可接纳617个任务再多则会执行默认拒绝策略ThreadPoolExecutor executor new ThreadPoolExecutor(5,6,1000l, TimeUnit.MILLISECONDS,new ArrayBlockingQueue(1));Runnable task new Runnable() {Overridepublic void run() {System.out.println(count);try {Thread.sleep(1000000000l);} catch (InterruptedException e) {throw new RuntimeException(e);}}};for(int i0;i8;i){executor.execute(task);//抛出RejectedExecutionException}System.out.println(executor.getActiveCount());} Task提交流程 coreThread -- queue -- maxThread -- handler 若运行线程少于corePoolSize尝试以给task启动一个新的core线程task进入BlockQueue排队BlockQueue已满添加新线程。失败则拒绝该task执行拒绝策略 Thread回收 回收逻辑Runnable状态线程数ctl减1从工作线程HashSet中移除工作线程Worker对象 回收超过keepAliveTime之外的非core线程回收超过keepAliveTime的core线程且allowCoreThreadTimeOuttrue 线程池任务管理
获取活跃线程数 ThreadPoolExecutor.getActiveCount()。线程池中正在运行的线程个数包括核心线程队列满后新建的非核心线程 static volatile int count 0;public static void main(String[]args) throws InterruptedException {ThreadPoolExecutor executor new ThreadPoolExecutor(5,9,1000l,TimeUnit.MILLISECONDS,new ArrayBlockingQueue(1));Runnable task new Runnable() {Overridepublic void run() {System.out.println(count);try {Thread.sleep(1000000000l);} catch (InterruptedException e) {throw new RuntimeException(e);}}};for(int i0;i8;i){executor.execute(task);}
//输出为75个在核心线程1个在队列2个为新建线程System.out.println(活跃线程executor.getActiveCount());} 获取提交的task状态 ThreadPoolExecutor.getTaskCount()历史提交的task总数 ThreadPoolExecutor.getCompletedTaskCount()已完成task个数 取消任务
futrure.cancel() task提交后状态 线程未启动线程正在执行线程已结束 task未启动cancel后会从线程池的阻塞队列中remove掉task task已结束cancel对task不会有任何影响 task正在执行通过interrupted标志位在sleep/join/wait处抛出中断异常终止task执行 无future第三方库 该场景适用于调用第三方库无future返回值情况。可以通过在第三方库中例如cancelTask等方法中重写Future.cancel()取消task Java Executors线程池工具 Executors是java一个线程池工具便捷创建例如单个、固定数量、定时等特征的线程池。不同特征的线程池其参数不同。 newSingleThreadPool 适用于提交的任务按顺序执行场景核心线程数最大线程数1一直存活如果任务异常中断了线程则创建一个新线程使用链表阻塞无界队列默认线程工厂Executors.defaultThreadFactory()默认阻塞策略AbortPolicy 短期提交任务过多则队列溢出内存溢出 public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueueRunnable()));}
cachedThreadPool 适用于执行许多短期(60s)异步任务场景核心线程为0最大线程为Integer.MAX_VALUE存活60s使用同步队列SynchronousQueue默认线程工厂Executors.defaultThreadFactory()默认阻塞策略AbortPolicy 短期提交任务过多则一直创建线程内存溢出 SynchronousQueue同步队列队列中不存储元素元素的offer和take阻塞对应 public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueueRunnable());
}
newFixedThreadPool 适用于执行IO较少异步任务场景核心线程最大线程输入参数线程创建后不回收使用LinkedBlockingQueue阻塞无界队列默认线程工厂Executors.defaultThreadFactory()默认阻塞策略AbortPolicy 短期提交任务过多则队列溢出内存溢出 public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueueRunnable());}
newThreadScheduledExecutor 适用于单一定时任务核心线程数1最大线程数Integer.MAX_VALUE一直存活使用优先级队列DelayedWorkQueue定时默认线程工厂Executors.defaultThreadFactory()默认阻塞策略AbortPolicy DelayedWorkQueue优先级队列底层使用“堆”数据结构实现 ExecutorService executorService Executors.newSingleThreadScheduledExecutor();
public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());}
SpringBoot线程池 SpringBoot线程池在JUC包下ThreadPoolExecutor基础上进行封装通过注入Bean或注解的方式使用。SpringBoot提供的线程池包括普通提交task的线程池和定时线程池。 提交task方式 通过Configuration注解和Bean注解注入定义的ThreadPoolTaskExecutor对象通过Autowired注入使用的threadPoolTaskExecutor对象通过threadPoolTaskExecutor的submit()或execute()方法提交任务。 注意Autowired注入Bean注解对象时默认是Bean对象的方法名 Configuration
public class TaskThreadPoolConfig {
//将线程池注入Spring IOCBeanpublic ThreadPoolTaskExecutor threadPoolTimeoutExecutor() {ThreadPoolTaskExecutor threadPoolTaskExecutor new ThreadPoolTaskExecutor();threadPoolTaskExecutor.setCorePoolSize(Runtime.getRuntime().availableProcessors() * 2);threadPoolTaskExecutor.initialize();return threadPoolTaskExecutor;}//注入线程池对象AutowiredThreadPoolTaskExecutor threadPoolTimeoutExecutor;//提交任务
public void test(){threadPoolTimeoutExecutor.submit(()-{runTask();});}
}
注解方式 通过Configuration注解和Bean注解注入定义的ThreadPoolTaskExecutor对象通过Async注解异步执行方法方法可以返回task的Future句柄或返回void 注意Bean注解可以添加线程池名字异步方法Async可以指定线程池名字 Configuration
public class TaskThreadPoolConfig {Bean(value test-threadpool)//定义线程池名public ThreadPoolTaskExecutor threadPoolTimeoutExecutor() {ThreadPoolTaskExecutor threadPoolTaskExecutor new ThreadPoolTaskExecutor();threadPoolTaskExecutor.setCorePoolSize(Runtime.getRuntime().availableProcessors() * 2);threadPoolTaskExecutor.initialize();return threadPoolTaskExecutor;}//方法上添加注解该方法异步执行方法可以返回Future任务句柄或voidAsync(value test-threadpool)//指定线程池public FutureObject runTask(){System.out.println(--);return new AsyncResult(true);}
}
取消任务 获取task的Future句柄通过future.cancel(true)取消任务。其内部则通过翻转interrupted标志位遇到例如sleep、wait、join等则抛出中断异常终止执行task的线程。 AutowiredThreadPoolTaskExecutor threadPoolTimeoutExecutor;public static void main(String []args){Future? future threadPoolTimeoutExecutor.submit(()-{try {Thread.sleep(1000l);} catch (InterruptedException e) {throw new RuntimeException(e);}});if(!future.isDone()){//task未结束future.cancel(true);//翻转执行task的线程的中断标志位遇到例如sleepjoinwait等抛出中断异常终止task}}
觉得不错点个吧