国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Java并發(fā)編程

2019-11-14 21:45:07
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
java并發(fā)編程 - Latch和Barrier的區(qū)別

之所以把Latch與Barrier放在一起比較是因?yàn)樗麄兘o人一種相似的感覺(jué)。他們都是阻塞一些行為直至某個(gè)事件發(fā)生,但Latch是等待某個(gè)事件發(fā)生,而B(niǎo)arrier是等待線(xiàn)程。

先比較一下JCip中對(duì)二者的描述:

  • 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。

    即,閉鎖可以延遲線(xiàn)程執(zhí)行直至達(dá)到相應(yīng)的結(jié)束狀態(tài)。閉鎖就像一個(gè)大門(mén),未到達(dá)結(jié)束狀態(tài)相當(dāng)于大門(mén)緊閉,不讓任何線(xiàn)程通過(guò)。而到達(dá)結(jié)束狀態(tài)后,大門(mén)敞開(kāi),讓所有的線(xiàn)程通過(guò),但是一旦敞開(kāi)后不會(huì)再關(guān)閉。閉鎖可以用來(lái)確保一些活動(dòng)在某個(gè)事件發(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直譯為"柵欄",我也很喜歡這個(gè)叫法。柵欄可以使一組執(zhí)行在一處匯集,也就是說(shuō)我們可以用柵欄將一個(gè)問(wèn)題分解成多個(gè)獨(dú)立的子問(wèn)題,并在執(zhí)行結(jié)束后在同一處進(jìn)行匯集。當(dāng)線(xiàn)程到達(dá)匯集地后調(diào)用await,await方法會(huì)出現(xiàn)阻塞直至其他線(xiàn)程也到達(dá)匯集地。如果所有的線(xiàn)程都到達(dá)就可以通過(guò)柵欄,也就是所有的線(xiàn)程得到釋放,而且柵欄也可以被重新利用。

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

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.

閉鎖從來(lái)都是帶著事件的觸發(fā)次數(shù)。await方法會(huì)一直阻塞至countDown方法將次數(shù)變成0為止,所有的線(xiàn)程被釋放才能進(jìn)行后續(xù)的工作。但這種現(xiàn)象只能出現(xiàn)一次,也就是說(shuō)觸發(fā)次數(shù)不會(huì)被重置。如果你想要一個(gè)可重置次數(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.)

這種行為阻塞的典型用法之一就是將某個(gè)問(wèn)題分成多個(gè)部分,每個(gè)部分用不同的線(xiàn)程負(fù)責(zé),并記得減少閉鎖設(shè)置的次數(shù)。當(dāng)所有線(xiàn)程的工作結(jié)束后將通過(guò)await方法造成的阻塞,如果我們需要反復(fù)進(jìn)行這樣的工作就需要使用柵欄。

好了,既然Doug Lea老師將同一個(gè)觀點(diǎn)闡述了這么多遍,剩下就是放心大膽地使用了,也許我們將問(wèn)題想得太復(fù)雜了。下面貼出栗子,由一個(gè)startGate攔住所有線(xiàn)程的執(zhí)行,當(dāng)所有線(xiàn)程就緒完成后調(diào)用countDown將它們釋放,而另一扇大門(mén)——endGate后面正等著計(jì)算執(zhí)行時(shí)間,而endGate等待的事件由這些線(xiàn)程觸發(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);        }    }));}

接著試試柵欄,沒(méi)有搞任何復(fù)雜的東西,注意countSupposed%partyCount,主要是想用這個(gè)體現(xiàn)一下柵欄是否可以反復(fù)使用多次。如果countSupposed%partyCount的結(jié)果恰好為0,所有線(xiàn)程執(zhí)行結(jié)束后,主線(xiàn)程也會(huì)正常結(jié)束。反之則會(huì)一直阻塞下去,如果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);}

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 裕民县| 滦南县| 射阳县| 乐东| 略阳县| 宁南县| 远安县| 武汉市| 喀喇| 平利县| 北京市| 贡觉县| 元朗区| 长丰县| 岳阳市| 南通市| 潞西市| 望城县| 牙克石市| 封丘县| 余姚市| 平遥县| 镇江市| 九龙城区| 黄龙县| 偃师市| 石屏县| 区。| 梧州市| 高碑店市| 清涧县| 湘潭市| 博爱县| 建昌县| 高邮市| 克什克腾旗| 宁强县| 庆安县| 眉山市| 太仆寺旗| 三台县|