Java countDownLatch如何實現(xiàn)多線程任務(wù)阻塞等待
我這里需要通過多線程去處理數(shù)據(jù),然后在所有數(shù)據(jù)都處理完成后再往下執(zhí)行。這里就用到了CountDownLatch。把countdownlatch作為參數(shù)傳入到每個線程類里,在線程中處理完數(shù)據(jù)后執(zhí)行countdown方法。在所有countdownlatch歸零后,其await方法結(jié)束阻塞狀態(tài)而往下執(zhí)行。
具體代碼如下:
將多線程任務(wù)提交線程池
@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; } //通過定時任務(wù)調(diào)用的fetch方法,為了避免定時任務(wù)在多次執(zhí)行中失效,通異步指定線程池的方式進行調(diào)用 @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; } //作為參數(shù)將CountDownLatch傳入 InnerRunner innerRunner = new InnerRunner(downLatch, tagNew); executor.execute(innerRunner); } try { //等待線程執(zhí)行完畢,如果十分鐘后還沒結(jié)束也會停止阻塞狀態(tài) downLatch.await(10,TimeUnit.MINUTES); fetchFlag.getAndSet(true); } catch (Throwable e) { log.error("fetch()方法發(fā)生錯誤:{}", e); fetchFlag.getAndSet(true); //e.printStackTrace(); } finally { fetchFlag.getAndSet(true); } } else { log.info("=======上次抓取尚未結(jié)束========="); } }
InnerRunner為要執(zhí)行具體任務(wù)的線程類
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塊中,以保證即使在拋出異常的情況下也算執(zhí)行了此次任務(wù),countdown會被執(zhí)行 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 { //肯定會被執(zhí)行 downLatch.countDown(); } }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Spring Cloud負載均衡重要組件Ribbon中重要類的用法
本篇文章主要介紹了詳解Spring Cloud負載均衡重要組件Ribbon中重要類的用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03SpringBoot多數(shù)據(jù)源配置并通過注解實現(xiàn)動態(tài)切換數(shù)據(jù)源
本文主要介紹了SpringBoot多數(shù)據(jù)源配置并通過注解實現(xiàn)動態(tài)切換數(shù)據(jù)源,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08Mybatis批量插入數(shù)據(jù)的兩種方式總結(jié)與對比
批量插入功能是我們?nèi)粘9ぷ髦斜容^常見的業(yè)務(wù)功能之一,下面這篇文章主要給大家介紹了關(guān)于Mybatis批量插入數(shù)據(jù)的兩種方式總結(jié)與對比的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-01-01SpringBoot基于SpringSecurity表單登錄和權(quán)限驗證的示例
這篇文章主要介紹了SpringBoot基于SpringSecurity表單登錄和權(quán)限驗證的示例。文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09Java和C語言分別實現(xiàn)水仙花數(shù)及拓展代碼
這篇文章主要介紹了分別用Java和C語言實現(xiàn)水仙花數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-11-11Spring Boot 2 實戰(zhàn):自定義啟動運行邏輯實例詳解
這篇文章主要介紹了Spring Boot 2 實戰(zhàn):自定義啟動運行邏輯,結(jié)合實例形式詳細分析了Spring Boot 2自定義啟動運行邏輯詳細操作技巧與注意事項,需要的朋友可以參考下2020-05-05