當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Java CountDownLatch And CyclicBarrier的區別用法及代碼示例


盡管 CountDownLatchCyclicBarrier 都用作允許至少一個線程等待的同步幫助,但它們之間還是有一定的區別。了解 Java 中 CountDownLatch 和 CyclicBarrier 之間的對比將幫助您選擇何時這些實用程序之一將為您提供更好的服務,顯然這也是一個不錯的 Java 查詢問題。

CountDownLatch 是一個等待多個線程完成或調用countDown() 的線程。當所有線程都調用了countDown()時,等待線程繼續執行。

例子:

Java


// Java Program to demonstrate Usage of CountDownLatch
// Its used when a thread needs to wait for other
// threads before starting its work
// Importing required classes
import java.util.concurrent.CountDownLatch;
// Main class
public class CountDownLatchDemo {
    // Main driver method
    public static void main(String args[])
        throws InterruptedException
    {
        // Let us create task that is going to
        // wait for four threads before it starts
        CountDownLatch latch = new CountDownLatch(4);
        // Creating worker threads
        Worker first = new Worker(1000, latch, "WORKER-1");
        Worker second = new Worker(2000, latch, "WORKER-2");
        Worker third = new Worker(3000, latch, "WORKER-3");
        Worker fourth = new Worker(4000, latch, "WORKER-4");
        // Starting above 4 threads
        first.start();
        second.start();
        third.start();
        fourth.start();
        // The main task waits for four threads
        latch.await();
        // Main thread has started
        System.out.println(Thread.currentThread().getName()
                           + " has finished");
    }
}
// A class to represent threads for which
// the main thread waits.
class Worker extends Thread {
    private int delay;
    private CountDownLatch latch;
    public Worker(int delay, CountDownLatch latch,
                  String name)
    {
        super(name);
        this.delay = delay;
        this.latch = latch;
    }
    @Override public void run()
    {
        try {
            Thread.sleep(delay);
            latch.countDown();
            System.out.println(
                Thread.currentThread().getName()
                + " finished");
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
輸出
WORKER-1 finished
WORKER-2 finished
WORKER-3 finished
WORKER-4 finished
main has finished

CyclicBarrier是當不同的線程相互等待(互相等待)並且當所有線程都完成執行時,需要在父線程中合並結果。

示例

Java


// Java program to demonstrate Execution on Cyclic Barrier
// Importing required classes
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
// Class 1
// Class implementing Runnable interface
class Computation1 implements Runnable {
    public static int product = 0;
    public void run()
    {
        product = 2 * 3;
        try {
            // thread1 awaits for other threads
            Tester.newBarrier.await();
        }
        catch (InterruptedException
               | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}
// Class 2
// Implementing Runnable interface
class Computation2 implements Runnable {
    public static int sum = 0;
    public void run()
    {
        // check if newBarrier is broken or not
        System.out.println("Is the barrier broken? - "
                           + Tester.newBarrier.isBroken());
        sum = 10 + 20;
        try {
            Tester.newBarrier.await(3000,
                                    TimeUnit.MILLISECONDS);
            // number of parties waiting at the barrier
            System.out.println(
                "Number of parties waiting at the barrier "
                + "at this point = "
                + Tester.newBarrier.getNumberWaiting());
        }
        catch (InterruptedException
               | BrokenBarrierException e) {
            e.printStackTrace();
        }
        catch (TimeoutException e) {
            e.printStackTrace();
        }
    }
}
public class Tester implements Runnable {
    // create a static CyclicBarrier instance
    public static CyclicBarrier newBarrier
        = new CyclicBarrier(3);
    public static void main(String[] args)
    {
        // parent thread
        Tester test = new Tester();
        Thread t1 = new Thread(test);
        // Starting the thread using start() method
        t1.start();
    }
    // Method
    public void run()
    {
        // Print statement
        System.out.println(
            "Number of parties required to trip the barrier = "
            + newBarrier.getParties());
        System.out.println(
            "Sum of product and sum = "
            + (Computation1.product + Computation2.sum));
        // Creating object of class 1 objects
        // on which the child thread has to run
        Computation1 comp1 = new Computation1();
        Computation2 comp2 = new Computation2();
        // creation of child thread
        Thread t1 = new Thread(comp1);
        Thread t2 = new Thread(comp2);
        // Moving child thread to runnable state
        t1.start();
        t2.start();
        try {
            // parent thread awaits
            Tester.newBarrier.await();
        }
        catch (InterruptedException
               | BrokenBarrierException e) {
            // Display exceptions along with line number
            // using printStackTrace() method
            e.printStackTrace();
        }
        // barrier breaks as the number of thread waiting
        // for the barrier at this point = 3
        System.out.println(
            "Sum of product and sum = "
            + (Computation1.product + Computation2.sum));
        // Resetting the newBarrier
        newBarrier.reset();
        System.out.println("Barrier reset successful");
    }
}
輸出
Number of parties required to trip the barrier = 3
Sum of product and sum = 0
Is the barrier broken? - false
Number of parties waiting at the barrier at this point = 0
Sum of product and sum = 36
Barrier reset successful

CountDownLatch 和 CyclicBarrier 之間的區別

CountDownLatch

CyclicBarrier

CountDownLatch 是一個線程在不同線程對鎖存器進行計數直至其到達零時進行查找的結構。 CyclicBarrier 是一個可重用的構造,其中一組線程一起等待,直到整個線程出現。到那時,障礙就被打破了,可以選擇采取行動。
CountDownLatch 記錄任務計數。 CyclicBarrier 保存線程計數。
在CountDownLatch中,單線程可以多次倒計時,這會減少調用countdown()方法的次數。 在CyclicBarrier中,單線程隻能調用await一次,這隻會將屏障計數減少一,即使多次調用awaits()方法也是如此。
當我們使用 CountDownLatch 時,您必須指定編號。創建 CountDownLatch 對象時調用 countdown() 方法的次數。 當我們使用CyclicBarrier時,必須指定編號。應調用 await() 函數來觸發屏障的線程數。
它被初始化為N,用於使一個線程處於待機狀態,直到N個字符串完成某個活動,或者某個活動已經完成N次。 如果您將 CyclicBarrier 初始化為 3,則意味著您無論如何都應該有 3 個字符串來調用 await()。
CountDownLatch無法重複使用,當計數為零時無法重置。 CyclicBarrier可以在釋放持有線程後重複使用。
在 CountDownLatch 中,隻有當前有問題的線程會拋出特殊情況/異常。 在 CyclicBarrier 中,如果線程遇到問題(超時、中斷),則達到 await() 的各種線程都會出現特殊情況/異常。
這是可以先進的。 這是不先進的。
如果當前線程被中斷,則會拋出異常InterruptedException。它不會影響其他線程。 如果一個線程在等待時被中斷,則所有其他等待線程將拋出異常BrokenBarrierException


相關用法


注:本文由純淨天空篩選整理自tarunsinghwap7大神的英文原創作品 Difference Between CountDownLatch And CyclicBarrier in Java。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。