当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。