日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java barrier_Java - Latch和Barrier的区别

發(fā)布時間:2025/3/11 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java barrier_Java - Latch和Barrier的区别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

之所以把Latch與Barrier放在一起比較是因為他們給人一種相似的感覺。

他們都是阻塞一些行為直至某個事件發(fā)生,但Latch是等待某個事件發(fā)生,而Barrier是等待線程。

先比較一下JCIP中對二者的描述:

Latch

A latch is a synchronizer that can delay the progress of threads until it reaches its terminal state.

A latch acts as a gate: until the latch reaches the terminal state the gate is closed and no thread can pass, and in the terminal state the gate opens, allowing all threads to pass.

Once the latch reaches the terminal state, it cannot change state again, so it remains open forever.

Latches can be used to ensure that certain activities do not proceed until other one-time activities complete。

即,閉鎖可以延遲線程執(zhí)行直至達(dá)到相應(yīng)的結(jié)束狀態(tài)。閉鎖就像一個大門,未到達(dá)結(jié)束狀態(tài)相當(dāng)于大門緊閉,不讓任何線程通過。

而到達(dá)結(jié)束狀態(tài)后,大門敞開,讓所有的線程通過,但是一旦敞開后不會再關(guān)閉。

閉鎖可以用來確保一些活動在某個事件發(fā)生后執(zhí)行。

Barrier

CyclicBarrier allows a fixed number of parties to rendezvous repeatedly at a barrier point and is useful in parallel iterative algorithms that break down a problem into a fixed number of independent subproblems.

Threads call await when they reach the barrier point, and await blocks until all the threads have reached the barrier point.

If all threads meet at the barrier point, the barrier has been successfully passed, in which case all threads are released and the barrier is reset so it can be used again.

很多人都把Barrier直譯為"柵欄",我也很喜歡這個叫法。

柵欄可以使一組執(zhí)行在一處匯集,也就是說我們可以用柵欄將一個問題分解成多個獨(dú)立的子問題,并在執(zhí)行結(jié)束后在同一處進(jìn)行匯集。

當(dāng)線程到達(dá)匯集地后調(diào)用await,await方法會出現(xiàn)阻塞直至其他線程也到達(dá)匯集地。

如果所有的線程都到達(dá)就可以通過柵欄,也就是所有的線程得到釋放,而且柵欄也可以被重新利用。

另外,下面javadoc中對二者之間區(qū)別的說明:

A CountDownLatch is initialized with a given count.

The await methods block until the current count reaches zero due to invocations of the countDown method, after which all waiting threads are released and any subsequent invocations of await return immediately.

This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.

閉鎖從來都是帶著事件的觸發(fā)次數(shù)。

await方法會一直阻塞至countDown方法將次數(shù)變成0為止,所有的線程被釋放才能進(jìn)行后續(xù)的工作。

但這種現(xiàn)象只能出現(xiàn)一次,也就是說觸發(fā)次數(shù)不會被重置。

如果你想要一個可重置次數(shù)的閉鎖,那就用柵欄。

Another typical usage would be to divide a problem into N parts, describe each part with a Runnable that executes that portion and counts down on the latch, and queue all the Runnables to an Executor.

When all sub-parts are complete, the coordinating thread will be able to pass through await.

(When threads must repeatedly count down in this way, instead use a CyclicBarrier.)

這種行為阻塞的典型用法之一就是將某個問題分成多個部分,每個部分用不同的線程負(fù)責(zé),并記得減少閉鎖設(shè)置的次數(shù)。

當(dāng)所有線程的工作結(jié)束后將通過await方法造成的阻塞,如果我們需要反復(fù)進(jìn)行這樣的工作就需要使用柵欄。

好了,既然Doug Lea老師將同一個觀點(diǎn)闡述了這么多遍,剩下就是放心大膽地使用了,也許我們將問題想得太復(fù)雜了。

下面貼出栗子,由一個startGate攔住所有線程的執(zhí)行,當(dāng)所有線程就緒完成后調(diào)用countDown將它們釋放,而另一扇大門——endGate后面正等著計算執(zhí)行時間,而endGate等待的事件由這些線程觸發(fā):

public class TestHarness {

public static long timeTasks(int nThreads, final Runnable task)

throws InterruptedException {

final CountDownLatch startGate = new CountDownLatch(1);

final CountDownLatch endGate = new CountDownLatch(nThreads);

for (int i = 0; i < nThreads; i++) {

Thread t = new Thread() {

public void run() {

try {

startGate.await();

try {

task.run();

} finally {

endGate.countDown();

}

} catch (InterruptedException ignored) {

}

}

};

t.start();

}

long start = System.nanoTime();

startGate.countDown();

endGate.await();

long end = System.nanoTime();

return end - start;

}

}

執(zhí)行看看:

public static void main(String[] args) throws ExecutionException, InterruptedException {

System.out.println("cost :::"+TestHarness.timeTasks(10,new Runnable() {

@Override

public void run() {

int num = RandomUtils.nextInt(0,100);

if(num>50) try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Alvez ::"+ num);

}

}));

}

接著試試柵欄,沒有搞任何復(fù)雜的東西,注意countSupposed%partyCount,主要是想用這個體現(xiàn)一下柵欄是否可以反復(fù)使用多次。

如果countSupposed%partyCount的結(jié)果恰好為0,所有線程執(zhí)行結(jié)束后,主線程也會正常結(jié)束。

反之則會一直阻塞下去,如果countSupposed%partyCount結(jié)果大于1且不為0,其結(jié)果就是我們看到"let's go to the barrier !!"出現(xiàn)的次數(shù):

public static void barrierTest(int partyCount, int countSupposed) {

if(partyCount<1 || countSupposed < 1) throw new IllegalArgumentException();

final CyclicBarrier barrier = new CyclicBarrier(partyCount,new Runnable() {

@Override

public void run() {

System.out.println("let's go barrier !!");

}

});

System.out.println(countSupposed%partyCount==0?"let's show the smooth!!":"....but blocked");

for (int i = 0; i < countSupposed; i++) {

Runnable runnable = new Runnable() {

@Override

public void run() {

try {

barrier.await();

System.out.println(Thread.currentThread().getName() + " show!!");

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

}

};

new Thread(runnable).start();

}

}

執(zhí)行:

public static void main(String[] args) {

barrierTest(11, 20);

}

總結(jié)

以上是生活随笔為你收集整理的java barrier_Java - Latch和Barrier的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。