Java使用CountDownLatch實(shí)現(xiàn)網(wǎng)絡(luò)同步請(qǐng)求的示例代碼
CountDownLatch 是一個(gè)同步工具類,用來(lái)協(xié)調(diào)多個(gè)線程之間的同步,它能夠使一個(gè)線程在等待另外一些線程完成各自工作之后,再繼續(xù)執(zhí)行。
這里是使用CountDownLatch和多線程完成商品信息異步組裝:
import java.time.LocalDateTime; import java.util.StringJoiner; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @author 向振華 * @date 2023/01/04 14:01 */ public class Test { public static void main(String[] args) { // 創(chuàng)建線程池 ExecutorService executorService = Executors.newFixedThreadPool(10); CountDownLatch countDownLatch = new CountDownLatch(3); System.out.println("開(kāi)始 " + LocalDateTime.now()); StringJoiner sj = new StringJoiner("、"); // 線程1 executorService.execute(() -> { try { String do1 = do1(); sj.add(do1); } catch (Exception e) { e.printStackTrace(); } finally { countDownLatch.countDown(); } }); // 線程2 executorService.execute(() -> { try { String do2 = do2(); sj.add(do2); } catch (Exception e) { e.printStackTrace(); } finally { countDownLatch.countDown(); } }); // 線程3 executorService.execute(() -> { try { String do3 = do3(); sj.add(do3); } catch (Exception e) { e.printStackTrace(); } finally { countDownLatch.countDown(); } }); try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(sj.toString()); System.out.println("完成 " + LocalDateTime.now()); } private static String do1() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1查詢商品規(guī)格信息"); return "商品規(guī)格"; } private static String do2() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("2查詢商品價(jià)格信息"); return "商品價(jià)格"; } private static String do3() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("3查詢商品圖片信息"); return "商品圖片"; } }
輸出結(jié)果:
開(kāi)始 2023-01-04T14:16:40.441
1查詢商品規(guī)格信息
3查詢商品圖片信息
2查詢商品價(jià)格信息
商品規(guī)格、商品圖片、商品價(jià)格
完成 2023-01-04T14:16:45.468
知識(shí)補(bǔ)充
1.背景
- countDownLatch是在java1.5被引入,跟它一起被引入的工具類還有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。
- 存在于java.util.cucurrent包下
2.概念
countDownLatch這個(gè)類使一個(gè)線程等待其他線程各自執(zhí)行完畢后再執(zhí)行。
是通過(guò)一個(gè)計(jì)數(shù)器來(lái)實(shí)現(xiàn)的,計(jì)數(shù)器的初始值是線程的數(shù)量。每當(dāng)一個(gè)線程執(zhí)行完畢后,計(jì)數(shù)器的值就-1,當(dāng)計(jì)數(shù)器的值為0時(shí),表示所有線程都執(zhí)行完畢,然后在閉鎖上等待的線程就可以恢復(fù)工作了。
3.源碼
countDownLatch類中只提供了一個(gè)構(gòu)造器:
//參數(shù)count為計(jì)數(shù)值 public CountDownLatch(int count) { };
類中有三個(gè)方法是最重要的:
//調(diào)用await()方法的線程會(huì)被掛起,它會(huì)等待直到count值為0才繼續(xù)執(zhí)行 public void await() throws InterruptedException { }; //和await()類似,只不過(guò)等待一定的時(shí)間后count值還沒(méi)變?yōu)?的話就會(huì)繼續(xù)執(zhí)行 public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; //將count值減1 public void countDown() { };
4.示例
普通示例
public class CountDownLatchTest { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(2); System.out.println("主線程開(kāi)始執(zhí)行…… ……"); //第一個(gè)子線程執(zhí)行 ExecutorService es1 = Executors.newSingleThreadExecutor(); es1.execute(new Runnable() { @Override public void run() { try { Thread.sleep(3000); System.out.println("子線程:"+Thread.currentThread().getName()+"執(zhí)行"); } catch (InterruptedException e) { e.printStackTrace(); } latch.countDown(); } }); es1.shutdown(); //第二個(gè)子線程執(zhí)行 ExecutorService es2 = Executors.newSingleThreadExecutor(); es2.execute(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子線程:"+Thread.currentThread().getName()+"執(zhí)行"); latch.countDown(); } }); es2.shutdown(); System.out.println("等待兩個(gè)線程執(zhí)行完畢…… ……"); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("兩個(gè)子線程都執(zhí)行完畢,繼續(xù)執(zhí)行主線程"); } }
結(jié)果集:
主線程開(kāi)始執(zhí)行…… ……
等待兩個(gè)線程執(zhí)行完畢…… ……
子線程:pool-1-thread-1執(zhí)行
子線程:pool-2-thread-1執(zhí)行
兩個(gè)子線程都執(zhí)行完畢,繼續(xù)執(zhí)行主線程
到此這篇關(guān)于Java使用CountDownLatch實(shí)現(xiàn)網(wǎng)絡(luò)同步請(qǐng)求的示例代碼的文章就介紹到這了,更多相關(guān)Java CountDownLatch網(wǎng)絡(luò)同步請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于@Autowierd && @Resource 你真的了解嗎
這篇文章主要介紹了關(guān)于@Autowierd && @Resource的具體使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08java socket大數(shù)據(jù)傳輸丟失問(wèn)題及解決
這篇文章主要介紹了java socket大數(shù)據(jù)傳輸丟失問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08Mybatis中通過(guò)generator生成mapper、Dao、mapper.xml的方法
這篇文章主要介紹了Mybatis中通過(guò)generator生成mapper、Dao、mapper.xml的方法,需要的朋友可以參考下2017-01-01java如何把逗號(hào)分隔的String字符串轉(zhuǎn)int集合
這篇文章主要介紹了java實(shí)現(xiàn)把逗號(hào)分隔的String字符串轉(zhuǎn)int集合,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06Spring中的@PropertySource注解源碼詳細(xì)解析
這篇文章主要介紹了Spring中的@PropertySource注解源碼詳細(xì)解析,@PropertySource注解,標(biāo)注在配置類@Configuration上面,下面主要分析一下@PropertySource注解的處理過(guò)程,也就是怎么把配置信息從.properies文件放到environment中的,需要的朋友可以參考下2024-01-01