当前位置: 首页 > 后端技术 > Java

Java线程池四种拒绝策略

时间:2023-04-01 19:20:16 Java

jdk1.5版本新增JUC并发包,其中之一包含线程池。四种拒绝策略:拒绝策略类型说明1ThreadPoolExecutor.AbortPolicy默认拒绝策略,拒绝任务和抛出任务2ThreadPoolExecutor.CallerRunsPolicy使用调用线程直接运行任务3ThreadPoolExecutor.DiscardPolicy直接拒绝任务不抛出错误4ThreadPoolExecutor.DiscardOldestPolicy触发拒绝策略,as只要还有新的任务,阻塞队列中最老的任务就会一直被丢弃,新的任务会被添加到预先配置好的配置线程池中。核心线程和最大线程要设置的越小越好,分别设置1个和2个阻塞队列设置一个固定长度的有界队列,长度为1=1;//最大线程数intmaximumPoolSize=2;//线程存活时间longkeepAliveTime=10;//线程存活时间单位TimeUnitunit=TimeUnit.SECONDS;//有界队列遵循先进先出原则BlockingQueueworkQueue=newArrayBlockingQueue<>(1);//线程工厂ThreadFactorythreadFactory=Executors.defaultThreadFactory();创建线程任务创建线程任务,一个线程任务执行一秒:classTaskThreadimplementsRunnable{privateinti;publicTaskThread(inti){this.i=i;}@Overridepublicvoidrun(){try{TimeUnit.SECONDS.sleep(2);System.out.println("执行任务:"+i);}catch(InterruptedExceptione){e.printStackTrace();}}}拒绝策略1:AbortPolicy默认拒绝策略,拒绝任务并抛出任务//拒绝策略默认拒绝策略,拒绝任务并抛出异常:RejectedExecutionHandlerhandler=newThreadPoolExecutor.AbortPolicy();ThreadPoolExecutor线程池=newThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler);对于(inti=1;i<=5;i++){try{threadPool.execute(newTaskThread(i));}catch(Exceptione){System.out.println("【任务"+i+"】错误:"+e.getMessage());}}输出【Task】4error:Taskcom.test.controller.ThreadPoolController$TaskThread@5c0369c4rejectedfromjava.util.concurrent.ThreadPoolExecutor@50675690[Running,poolsize=2,activethreads=2,queuedtasks=1,已完成的任务=0]【任务】5错误:任务com.test.controller.ThreadPoolController$TaskThread@31b7dea0被java.util.concurrent.ThreadPoolExecutor@50675690拒绝[正在运行,池大小=2,活动线程=2,排队任务=1,completedtasks=0]Executedtasks:1Executedtasks:3Executedtasks:2max线程数+阻塞队列=3,执行到4或5时会抛出错误这里需要使用trycatch来捕获异常。任务1、2、3正常执行。如果提交的任务必须执行,可以将抛出的错误任务存储到redis中,然后定时从redis中获取任务,再提交执行。拒绝策略2:CallerRunsPolicy调用线程运行冗余任务。通过将上面的AbortPolicy替换为CallerRunsPolicy来替换拒绝策略。RejectedExecutionHandlerhandler=newThreadPoolExecutor.CallerRunsPolicy();执行任务,输出:执行任务:1执行任务:4执行任务:3执行任务:2执行任务:5最大线程数+阻塞队列=3,冗余任务会继续处理执行。拒绝策略三:DiscardPolicy拒绝任务而不抛出错误。替换策略,将CallerRunsPolicy替换为DiscardPolicy:RejectedExecutionHandlerhandler=newThreadPoolExecutor.DiscardPolicy();执行任务,输出:Executetask:1Executetask:3Executetask:2冗余线程任务提交被拒绝,只执行最大线程数+队列数的Block任务,不抛错。拒绝策略四:DiscardOldestPolicy只要有新的任务加入,就会一直丢弃阻塞队列中最老的任务,将新的任务加入阻塞队列。更改策略,将DiscardPolicy替换为DiscardOldestPolicy:RejectedExecutionHandlerhandler3=newThreadPoolExecutor.DiscardOldestPolicy();执行任务,输出:执行任务:3执行任务:1执行任务:5任务执行顺序为核心线程数—>阻塞队列—>最大线程数,其中任务1和任务3提交成功.因为任务2在阻塞队列中,后面的任务4挤掉了任务2,任务5又挤掉了任务4,所以最终还是执行了任务5。小结本文介绍四种线程拒绝策略。当工作任务大于最大线程+阻塞队列时,就会执行阻塞队列。AbortPolicy默认策略,拒绝任务,并抛出异常CallerRunsPolicy调用线程执行对应的任务DiscardPolicy拒绝任务,没有异常抛出新任务。如果您觉得文章对您有帮助,请点个赞吧!