成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

并發協調神器CountDownLatch和CyclicBarrier

開發 后端
CountDownLatch的適用場景更傾向于等待其他線程的任務完成,而CyclicBarrier更適用于多個線程在特定位置同步后繼續執行。兩者都是非常有用的并發控制工具,能夠幫助程序員更加靈活地管理多線程任務的執行順序。

1.引言

從Java的最初版本開始,就可以利用Java來進行多線程編程。正因為Java從最早的版本就支持多線程編程,程序員們才能夠利用Java強大的多線程機制來實現并發任務的執行。然而,多線程編程雖然強大,卻也帶來了一系列潛在的問題和挑戰。

假設有一個共享的咖啡機,多個同事在辦公室中使用它來沖泡咖啡。這里就存在著典型的多線程問題:

  • 競態條件(Race Condition):多個同事同時按下沖泡按鈕,如果沒有適當的控制和同步機制,可能會導致咖啡機出現異常行為,比如一次性沖出過多的咖啡或者沒有沖出咖啡。
  • 死鎖(Deadlock):例如,如果兩個同事分別占用了添加水和放置咖啡粉的步驟,但互相等待對方完成,那么咖啡機就無法繼續工作了。
  • 數據同步(Data Synchronization):確保每個同事知道何時該添加水、何時該放置咖啡粉,以及何時可以開始沖泡,從而避免出現混亂或資源爭奪的情況。

2.并發引出的問題

并發引發問題的根源歸咎于三個方面:

(1)可見性: CPU緩存引起

可見性:一個線程對共享變量的修改,另外一個線程能夠立刻看到。

舉個簡單的例子,看下面這段代碼:

//線程1執行的代碼
int i = 0;
i = 10;
 
//線程2執行的代碼
j = i;

在多線程環境下,如果線程1對變量i進行了修改,但由于CPU緩存的存在,這個修改可能并不會立即被其他線程(比如線程2)所看到。這樣,在線程2執行j = i;時,它可能讀取到的是舊的i的值,而不是線程1修改后的新值。

(2)原子性: 分時復用引起

原子性:即一個操作或者多個操作 要么全部執行并且執行的過程不會被任何因素打斷,要么就都不執行。 經典的轉賬問題:比如從賬戶A向賬戶B轉1000元,那么必然包括2個操作:從賬戶A減去1000元,往賬戶B加上1000元。 試想一下,如果這2個操作不具備原子性,會造成什么樣的后果。假如從賬戶A減去1000元之后,操作突然中止。然后又從B取出了500元,取出500元之后,再執行 往賬戶B加上1000元 的操作。這樣就會導致賬戶A雖然減去了1000元,但是賬戶B沒有收到這個轉過來的1000元。 所以這2個操作必須要具備原子性才能保證不出現一些意外的問題。

(3)有序性: 重排序引起

有序性:即程序執行的順序按照代碼的先后順序執行。舉個簡單的例子,看下面這段代碼:

int i = 0;              
boolean flag = false;
i = 1;                //語句1  
flag = true;          //語句2

上面代碼定義了一個int型變量,定義了一個boolean類型變量,然后分別對兩個變量進行賦值操作。從代碼順序上看,語句1是在語句2前面的,那么JVM在真正執行這段代碼的時候會保證語句1一定會在語句2前面執行嗎? 不一定,為什么呢? 這里可能會發生指令重排序。

3.CountDownLatch和CyclicBarrier如何讓多線程步調一致

在多線程編程中,有時我們需要讓多個線程協同工作,以便在某個點上保持步調一致。Java中的CountDownLatch和CyclicBarrier就是用來實現這一目的的兩個重要工具。

(1)CountDownLatch

實現原理:

CountDownLatch是一個計數器,它允許一個或多個線程等待一組操作完成。其基本思想是,一個線程或多個線程在執行任務時,需要等待其他線程都執行完畢后才能繼續執行。CountDownLatch通過一個計數器來實現,當計數器為0時,等待的線程可以繼續執行。

這段代碼演示了使用CountDownLatch來實現多個線程之間的協同工作,確保它們按照預期順序執行。

import java.util.concurrent.CountDownLatch;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3); // 初始化計數器為3

        Runnable task = () -> {
            // 執行一些操作
            latch.countDown(); // 操作完成后將計數器減1
        };

        for (int i = 0; i < 3; i++) {
            new Thread(task).start(); // 啟動3個線程執行任務
        }

        latch.await(); // 等待計數器變為0
        System.out.println("所有操作已完成,多線程步調一致!");
    }
}

當3個線程都調用了countDown之后,主線程從await返回,并輸出"所有操作已完成,多線程步調一致!

(2)CyclicBarrier

實現原理:

字面意思回環柵欄,通過它可以實現讓一組線程等待至某個狀態之后再全部同時執行。叫做回環是因為當所有等待線程都被釋放以后,CyclicBarrier可以被重用。我們暫且把這個狀態就叫做barrier,當調用await()方法之后,線程就處于barrier了。

這段代碼演示了如何使用CyclicBarrier來實現多個線程在一個屏障點進行等待,并在達到該位置后同時繼續執行后續操作。CyclicBarrier常用于多個線程協同工作,并且需要在某個點上實現同步,在實際場景中可以用于控制多線程分階段執行任務的情況。

import java.util.concurrent.CyclicBarrier;

public class Main {
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3, () -> {
            System.out.println("所有線程已到達柵欄位置,開始執行后續操作!");
        });

        Runnable task = () -> {
            try {
                // 執行一些操作
                barrier.await(); // 等待其他線程到達柵欄位置
            } catch (Exception e) {
                e.printStackTrace();
            }
        };

        for (int i = 0; i < 3; i++) {
            new Thread(task).start(); // 啟動3個線程執行任務
        }
    }
}

4.總結

CountDownLatch 和 CyclicBarrier 都是 Java 多線程編程中用于控制多個線程協同工作的工具,但它們之間有一些關鍵的區別,用法的區別如下:CountDownLatch 主要用來解決一個線程等待多個線程的場景,可以類比旅游團團長要等待所有的游客到齊才能去下一個景點;而CyclicBarrier 是一組線程之間互相等待,更像是幾個驢友之間不離不棄。

(1)功能不同:

  • CountDownLatch 用于讓一個或多個線程等待其他線程完成操作,達到某個條件后再繼續執行。
  • CyclicBarrier 則用于讓多個線程在指定位置處進行等待,然后同時繼續執行。

(2)重用性:

  • CountDownLatch 是一次性的,一旦計數器變為0,就不能再重置使用。
  • CyclicBarrier 可以被重復使用,當所有線程都到達屏障點后,可以選擇重置柵欄來進行下一輪等待。

(3)回調操作:

  • CountDownLatch 沒有提供回調操作的機制。
  • CyclicBarrier 可以在所有線程到達屏障點后執行指定的合并操作。

(4)適用場景:

  • CountDownLatch 適用于一組線程需要等待另一組線程執行完畢后再執行的情況,或者等待某些條件滿足后再繼續執行。
  • CyclicBarrier 適用于多個線程需要在特定點同步,并且在這一點上需要同時繼續執行后續操作的情況。

總的來說,CountDownLatch的適用場景更傾向于等待其他線程的任務完成,而CyclicBarrier更適用于多個線程在特定位置同步后繼續執行。兩者都是非常有用的并發控制工具,能夠幫助程序員更加靈活地管理多線程任務的執行順序。

責任編輯:姜華 來源: 今日頭條
相關推薦

2014-03-14 10:34:28

JavaJava并發

2019-09-16 09:23:34

高并發編程CountDownLaCyclicBarri

2025-04-23 08:31:26

Java并發框架

2024-11-13 15:09:57

Java線程開發

2024-04-29 09:06:46

線程初始化源碼

2020-12-03 11:15:21

CyclicBarri

2021-08-26 08:03:30

大數據Zookeeper選舉

2021-03-18 00:14:29

JavaCyclicBarri高并發

2020-12-04 19:28:53

CountDownLaPhaserCyclicBarri

2021-03-11 00:05:55

Java高并發編程

2021-02-26 13:08:27

Java高并發AQS

2022-09-07 18:32:57

并發編程線程

2024-10-31 11:16:19

高并發并發集JDK

2020-12-21 07:54:46

CountDownLa用法源碼

2025-01-13 09:24:32

2023-11-28 08:01:48

互斥鎖共享資源

2022-11-27 08:12:11

RocketMQ源碼工具類

2021-07-07 07:09:49

Redisson分布式鎖源碼

2021-04-21 07:53:12

Java限流器管理

2021-07-30 11:21:39

物聯網網絡安全IoT
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩综合精品 | 精品欧美一区免费观看α√ | 天天影视色综合 | 久在线 | 国产精品视频一区二区三区 | 亚洲欧美日韩精品久久亚洲区 | 中文字幕av第一页 | 欧美激情综合网 | 日韩欧美国产精品一区 | 天天干,夜夜操 | 欧美黄色一区 | 日韩在线三级 | 久久av一区二区三区 | 精品欧美久久 | 国产乱码精品一区二区三区中文 | 日本又色又爽又黄的大片 | 天堂一区 | 天天操天天摸天天干 | 欧美久久精品一级黑人c片 91免费在线视频 | 粉嫩国产精品一区二区在线观看 | 四虎影院免费在线 | 日韩精品999 | 国产在线a | 97精品国产97久久久久久免费 | 久久最新精品 | 日韩中文字幕一区二区 | 亚洲久草视频 | www国产亚洲精品 | 久久久久国产一区二区三区四区 | 国产一区二区三区网站 | 草草草久久久 | 国产日韩一区二区三区 | 欧美精品一区二区三区一线天视频 | 国产精品一区二区欧美黑人喷潮水 | 99pao成人国产永久免费视频 | 久久精品毛片 | 精品成人| 久久一区二区三区四区 | 欧美三级电影在线播放 | 大陆一级毛片免费视频观看 | 一区二区三区在线免费观看 |