Java中CountDownLatch和CyclicBarrier的区别

Java中CountDownLatch和CyclicBarrier的区别

尽管CountDownLatch和CyclicBarrier都被用作同步帮助,允许至少一个线程等待,但它们之间有明显的区别。了解Java中CountDownLatch和CyclicBarrier之间的对比,将有助于你选择这些工具中的某一个为你提供更好的服务,显然这也是一个很好的Java调查问题。

CountDownLatch是一个线程在等待多个线程完成或调用 countDown() 。当所有线程都调用了 countDown() ,等待的线程继续执行。

示例代码:

// 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
main has finished
WORKER-4 finished

循环障碍(CyclicBarrier)是指不同的线程互相挂起(互相等待),当所有的线程都完成了它们的执行,结果需要在父线程中进行合并。

示例代码:

// 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是一种构造,一个线程在寻找的同时,不同的线程在锁存器上进行计数,直到到达0。 循环屏障(CyclicBarrier)是一个可重复使用的结构,在这个结构中,一个线程的聚集在一起,直到所有的线程都出现。到那时,屏障就会被打破,可以交替进行移动。
CountDownLatch保持对任务的计数。 循环屏障(CyclicBarrier)保持着线程的数量。
在CountDownLatch中,单线程可以倒计时一次以上,这将减少countdown()方法被调用的次数。 在CyclicBarrier中,单线程可以只调用awits一次,这将使障碍计数减少一次,即使调用awits()方法超过一次。
当使用CountDownLatch时,你必须在创建CountDownLatch对象时指定对倒计时()方法的调用次数。 当使用CyclicBarrier时,你必须指定调用await()函数来跳过障碍的线程数量。
CountDownLatch被初始化为N,用于使一个线程待命,直到N个字符串完成某些活动,或者某些活动已经完成了N次。 如果有一个初始化为3的CyclicBarrier,这意味着你在任何情况下都应该有3个字符串来调用await()。
CountDownLatch不能被重复使用,当计数到达0时,它不能被重置。 CyclicBarrier在持有线程被释放后可以被重新使用。
在CountDownLatch中,只有当前有问题的线程会抛出一个特殊情况/异常。 在CyclicBarrier中,如果一个线程遇到了问题(超时、中断),已经到达await()的广泛的各种线程都会得到一个特殊情况/异常。
CountDownLatch是可以提前的。 CyclicBarrier是不可提前的。
如果当前线程被中断,它将抛出InterruptedException。它不会影响其他线程。 如果一个线程在等待时被打断,那么所有其他等待的线程将抛出BrokenBarrierException。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程