摘要:中提供了幾個比較常用的并發工具類,比如。是一個同步工具類,它允許一個或多個線程一直等待,直到其他線程的操作執行完畢再執行。從命名可以解讀到是倒數的意思,類似于我們倒計時的概念。
JUC中提供了幾個比較常用的并發工具類,比如CountDownLatch、CyclicBarrier、Semaphore。 其實在以前我們 課堂的演示代碼中,或多或少都有用到過這樣一些api,接下來我們會帶大家去深入研究一些常用的api。 CountDownLatch
countdownlatch是一個同步工具類,它允許一個或多個線程一直等待,直到其他線程的操作執行完畢再執行。從 命名可以解讀到countdown是倒數的意思,類似于我們倒計時的概念。 countdownlatch提供了兩個方法,一個是countDown,一個是await, countdownlatch初始化的時候需要傳入一 個整數,在這個整數倒數到0之前,調用了await方法的程序都必須要等待,然后通過countDown來倒數。
public static void main(String[] args) throws InterruptedException { ? ?CountDownLatch countDownLatch=new CountDownLatch(3); ? ?new Thread(()->{ ? ? ? ? ? ?countDownLatch.countDown(); ? },"t1").start(); ? ?new Thread(()->{ ? ? ? ? ? ?countDownLatch.countDown(); ? },"t2").start(); ? ?new Thread(()->{ ? ? ? ?countDownLatch.countDown(); ? },"t3").start(); ? ?countDownLatch.await(); ? ?System.out.println("所有線程執行完畢"); }
從代碼的實現來看,有點類似join的功能,但是比join更加靈活。CountDownLatch構造函數會接收一個int類型的 參數作為計數器的初始值,當調用CountDownLatch的countDown方法時,這個計數器就會減一。 通過await方法去阻塞去阻塞主流程
使用場景
1. 通過countdownlatch實現最大的并行請求,也就是可以讓N個線程同時執行,這個我也是在課堂上寫得比較多 的
2. 比如應用程序啟動之前,需要確保相應的服務已經啟動,比如我們之前在講zookeeper的時候,通過原生api連 接的地方有用到countDownLatch 源碼分析
CountDownLatch類存在一個內部類Sync,上節課我們講過,它是一個同步工具,一定繼承了 AbstractQueuedSynchronizer。很顯然,CountDownLatch實際上是是使得線程阻塞了,既然涉及到阻塞,就一 定涉及到AQS隊列 await
await函數會使得當前線程在countdownlatch倒計時到0之前一直等待,除非線程別中斷;從源碼中可以得知await 方法會轉發到Sync的acquireSharedInterruptibly
方法
public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } acquireSharedInterruptibly
這塊代碼主要是判斷當前線程是否獲取到了共享鎖; 上一節課提到過,AQS有兩種鎖類型,一種是共享鎖,一種是 獨占鎖,在這里用的是共享鎖; 為什么要用共享鎖,因為CountDownLatch可以多個線程同時通過。
public final void acquireSharedInterruptibly(int arg) ? ? ? ?throws InterruptedException { doAcquireSharedInterruptibly 獲取共享鎖 ? ?if (Thread.interrupted()) //判斷線程是否中斷 ? ? ? ?throw new InterruptedException(); ? ?if (tryAcquireShared(arg) < 0) //如果等于0則返回1,否則返回-1,返回-1表示需要阻塞 ? ? ? ?doAcquireSharedInterruptibly(arg); } 在這里,state的意義是count,如果計數器為0,表示不需要阻塞,否則,只有在滿足條件的情況下才會被喚醒
doAcquireSharedInterruptibly
獲取共享鎖
private void doAcquireSharedInterruptibly(int arg) ? ?throws InterruptedException { ? ?final Node node = addWaiter(Node.SHARED); //創建一個共享模式的節點添加到隊列中 ? ?boolean failed = true; ? ?try { ? ? ? ?for (;;) { //自旋等待共享鎖釋放,也就是等待計數器等于0。 ? ? ? ? ? ?final Node p = node.predecessor(); //獲得當前節點的前一個節點 ? ? ? ? ? ?if (p == head) { ? ? ? ? ? ? ? ?int r = tryAcquireShared(arg);//就判斷嘗試獲取鎖 ? ? ? ? ? ? ? ?if (r >= 0) {//r>=0表示計數器已經歸零了,則釋放當前的共享鎖 ? ? ? ? ? ? ? ? ? ?setHeadAndPropagate(node, r); ? ? ? ? ? ? ? ? ? ?p.next = null; // help GC ? ? ? ? ? ? ? ? ? ?failed = false; ? ? ? ? ? ? ? ? ? ?return; ? ? ? ? ? ? ? } ? ? ? ? ? } //當前節點不是頭節點,則嘗試讓當前線程阻塞,第一個方法是判斷是否需要阻塞,第二個方法是阻塞 ? ? ? ? ? ?if (shouldParkAfterFailedAcquire(p, node) && ? ? ? ? ? ? ? ?parkAndCheckInterrupt()) ? ? ? ? ? ? ? ?throw new InterruptedException(); ? ? ? } ? } finally { ? ? ? ?if (failed) ? ? ? ? ? ?cancelAcquire(node); ? } }
待續。。。。。。。。。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72632.html
摘要:在上篇文章實現簡單爬蟲框架單任務版爬蟲中我們實現了一個簡單的單任務版爬蟲,對于單任務版爬蟲,每次都要請求頁面,然后解析數據,然后才能請求下一個頁面。在上篇文章Golang實現簡單爬蟲框架(2)——單任務版爬蟲中我們實現了一個簡單的單任務版爬蟲,對于單任務版爬蟲,每次都要請求頁面,然后解析數據,然后才能請求下一個頁面。整個過程中,獲取網頁數據速度比較慢,那么我們就把獲取數據模塊做成并發執行。在...
摘要:在上篇文章實現簡單爬蟲框架單任務版爬蟲中我們實現了一個簡單的單任務版爬蟲,對于單任務版爬蟲,每次都要請求頁面,然后解析數據,然后才能請求下一個頁面。在上篇文章Golang實現簡單爬蟲框架(2)——單任務版爬蟲中我們實現了一個簡單的單任務版爬蟲,對于單任務版爬蟲,每次都要請求頁面,然后解析數據,然后才能請求下一個頁面。整個過程中,獲取網頁數據速度比較慢,那么我們就把獲取數據模塊做成并發執行。在...
摘要:如何使用優化高并發場景寫庫或者耗時計算在的接口中使用消息隊列,把要入庫的數據寫入的類型中。高容錯子進程異常奔潰時,主進程將重建子進程。高性能多進程運行,充分利用多個并行計算,性能強勁。 經常在群里聽到一些朋友問:TP 的項目怎么遷移到 mixphp 來處理高并發,我通常都是回復需要重寫,可是一個開發很久的 TP 項目,代碼量巨大,又怎么可能會花大量時間成本來重寫呢? 那么為何我們不嘗試...
摘要:有三種狀態運行關閉終止。類類,提供了一系列工廠方法用于創建線程池,返回的線程池都實現了接口。線程池的大小一旦達到最大值就會保持不變,在提交新任務,任務將會進入等待隊列中等待。此線程池支持定時以及周期性執行任務的需求。 這是java高并發系列第19篇文章。 本文主要內容 介紹Executor框架相關內容 介紹Executor 介紹ExecutorService 介紹線程池ThreadP...
摘要:線程的啟動與銷毀都與本地線程同步。操作系統會調度所有線程并將它們分配給可用的。框架的成員主要成員線程池接口接口接口以及工具類。創建單個線程的接口與其實現類用于表示異步計算的結果。參考書籍并發編程的藝術方騰飛魏鵬程曉明著 在java中,直接使用線程來異步的執行任務,線程的每次創建與銷毀需要一定的計算機資源開銷。每個任務創建一個線程的話,當任務數量多的時候,則對應的創建銷毀開銷會消耗大量...
摘要:新增新增模型方法,主動刷新數據表結構緩存。分布式并發模型是什么是一種與共享內存對應的并發模型,具有資源獨占性。都分布在不同的機器上。 One - 極簡 . 高性能 . 松耦合 . 分布式 . 可運行于多種環境(cli,apache/php-fpm,swoole) 碼云: https://gitee.com/vicself/onegithub: https://github.com/li...
閱讀 3046·2023-04-26 02:27
閱讀 2763·2021-11-22 13:54
閱讀 902·2021-11-12 10:36
閱讀 3753·2021-10-09 09:44
閱讀 3178·2021-10-09 09:41
閱讀 1223·2021-09-22 10:02
閱讀 2833·2019-08-30 15:56
閱讀 3106·2019-08-30 11:02