Java countDownLatch如何实现多线程任务阻塞等待 我这里需要通过多线程去处理数据,然后在所有数据都处理完成后再往下执行.这里就用到了CountDownLatch.把countdownlatch作为参数传入到每个线程类里,在线程中处理完数据后执行countdown方法.在所有countdownl
我这里需要通过多线程去处理数据,然后在所有数据都处理完成后再往下执行。这里就用到了CountDownLatch。把countdownlatch作为参数传入到每个线程类里,在线程中处理完数据后执行countdown方法。在所有countdownlatch归零后,其await方法结束阻塞状态而往下执行。
具体代码如下:
将多线程任务提交线程池
@Bean(name = "ggnews_executor")
public Executor postExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1);
executor.setMaxPoolSize(1);
executor.setQueueCapacity(1);
executor.setKeepAliveSeconds(120);
executor.setThreadNamePrefix("executor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
return executor;
}
//通过定时任务调用的fetch方法,为了避免定时任务在多次执行中失效,通异步指定线程池的方式进行调用
@Async("ggnews_executor")
public void fetch() {
if(fetchFlag.getAndSet(false)) {
List<FetchTag> tags = fetchTagService.selectFetchTagList(fetchTag);
CountDownLatch downLatch = new CountDownLatch(tags.size());
for (FetchTag tag : tags) {
FetchTag tagNew;
try {
tagNew =(FetchTag) tag.clone();
} catch (Throwable e) {
log.error("",e);
continue;
}
//作为参数将CountDownLatch传入
InnerRunner innerRunner = new InnerRunner(downLatch, tagNew);
executor.execute(innerRunner);
}
try {
//等待线程执行完毕,如果十分钟后还没结束也会停止阻塞状态
downLatch.await(10,TimeUnit.MINUTES);
fetchFlag.getAndSet(true);
} catch (Throwable e) {
log.error("fetch()方法发生错误:{}", e);
fetchFlag.getAndSet(true);
//e.printStackTrace();
} finally {
fetchFlag.getAndSet(true);
}
} else {
log.info("=======上次抓取尚未结束=========");
}
}
InnerRunner为要执行具体任务的线程类
private class InnerRunner implements Runnable {
private CountDownLatch downLatch;
private FetchTag tag;
private InnerRunner(CountDownLatch downLatch, FetchTag tag) {
this.downLatch = downLatch;
this.tag = tag;
}
@Override
public void run() {
//将countDown方法移入到具体方法中的finally块中,以保证即使在抛出异常的情况下也算执行了此次任务,countdown会被执行
fetchGG(tag.getTag(), downLatch);
//downLatch.countDown();
this.tag = null;
}
}
private static final String GOOGLE_URL_IN = "https://news.google.com/rss/search?hl=hi&gl=IN&ceid=IN:hi&q=";
public void fetchGG(String tag, CountDownLatch downLatch) {
try {
Document document = Jsoup.parse(new URL(GOOGLE_URL_IN + URLEncoder.encode("\"" + tag + "\"", "utf-8")), 30000);
Elements elements = document.getElementsByTag("item");
int rank = 1;
for (Element element : elements) {
String sourceTitle = element.getElementsByTag("title").get(0).text();
log.info("source title:" + sourceTitle);
}
} catch (Throwable e) {
log.info("fetch google url error", e);
} finally {
//肯定会被执行
downLatch.countDown();
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
沃梦达教程
本文标题为:Java countDownLatch如何实现多线程任务阻塞等待
猜你喜欢
- Springboot整合minio实现文件服务的教程详解 2022-12-03
- 基于Java Agent的premain方式实现方法耗时监控问题 2023-06-17
- Spring Security权限想要细化到按钮实现示例 2023-03-07
- Java实现顺序表的操作详解 2023-05-19
- JSP 制作验证码的实例详解 2023-07-30
- JSP页面间传值问题实例简析 2023-08-03
- Java中的日期时间处理及格式化处理 2023-04-18
- 深入了解Spring的事务传播机制 2023-06-02
- ExecutorService Callable Future多线程返回结果原理解析 2023-06-01
- SpringBoot使用thymeleaf实现一个前端表格方法详解 2023-06-06