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();
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。