Java countDownLatch如何实现多线程任务阻塞等待
我这里需要通过多线程去处理数据,然后在所有数据都处理完成后再往下执行。这里就用到了CountDownLatch。把countdownlatch作为参数传入到每个线程类里,在线程中处理完数据后执行countdown方法。在所有countdownlatch归零后,其await方法结束阻塞状态而往下执行。
具体代码如下:
将多线程任务提交线程池
@Bean(name="ggnews_executor") publicExecutorpostExecutor(){ ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor(); executor.setCorePoolSize(1); executor.setMaxPoolSize(1); executor.setQueueCapacity(1); executor.setKeepAliveSeconds(120); executor.setThreadNamePrefix("executor-"); executor.setRejectedExecutionHandler(newThreadPoolExecutor.DiscardPolicy()); returnexecutor; } //通过定时任务调用的fetch方法,为了避免定时任务在多次执行中失效,通异步指定线程池的方式进行调用 @Async("ggnews_executor") publicvoidfetch(){ if(fetchFlag.getAndSet(false)){ Listtags=fetchTagService.selectFetchTagList(fetchTag); CountDownLatchdownLatch=newCountDownLatch(tags.size()); for(FetchTagtag:tags){ FetchTagtagNew; try{ tagNew=(FetchTag)tag.clone(); }catch(Throwablee){ log.error("",e); continue; } //作为参数将CountDownLatch传入 InnerRunnerinnerRunner=newInnerRunner(downLatch,tagNew); executor.execute(innerRunner); } try{ //等待线程执行完毕,如果十分钟后还没结束也会停止阻塞状态 downLatch.await(10,TimeUnit.MINUTES); fetchFlag.getAndSet(true); }catch(Throwablee){ log.error("fetch()方法发生错误:{}",e); fetchFlag.getAndSet(true); //e.printStackTrace(); }finally{ fetchFlag.getAndSet(true); } }else{ log.info("=======上次抓取尚未结束========="); } }
InnerRunner为要执行具体任务的线程类
privateclassInnerRunnerimplementsRunnable{ privateCountDownLatchdownLatch; privateFetchTagtag; privateInnerRunner(CountDownLatchdownLatch,FetchTagtag){ this.downLatch=downLatch; this.tag=tag; } @Override publicvoidrun(){ //将countDown方法移入到具体方法中的finally块中,以保证即使在抛出异常的情况下也算执行了此次任务,countdown会被执行 fetchGG(tag.getTag(),downLatch); //downLatch.countDown(); this.tag=null; } }
privatestaticfinalStringGOOGLE_URL_IN="https://news.google.com/rss/search?hl=hi&gl=IN&ceid=IN:hi&q="; publicvoidfetchGG(Stringtag,CountDownLatchdownLatch){ try{ Documentdocument=Jsoup.parse(newURL(GOOGLE_URL_IN+URLEncoder.encode("\""+tag+"\"","utf-8")),30000); Elementselements=document.getElementsByTag("item"); intrank=1; for(Elementelement:elements){ StringsourceTitle=element.getElementsByTag("title").get(0).text(); log.info("sourcetitle:"+sourceTitle); } }catch(Throwablee){ log.info("fetchgoogleurlerror",e); }finally{ //肯定会被执行 downLatch.countDown(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。