zoukankan      html  css  js  c++  java
  • JAVA栅栏和闭锁的区别

      闭锁:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。即,一组线程等待某一事件发生,事件没有发生前,所有线程将阻塞等待;而事件发生后,所有线程将开始执行;闭锁最初处于封闭状态,当事件发生后闭锁将被打开,一旦打开,闭锁将永远处于打开状态。

      闭锁CountDownLatch唯一的构造方法CountDownLatch(int count),当在闭锁上调用countDown()方法时,闭锁的计数器将减1,当闭锁计数器为0时,闭锁将打开,所有线程将通过闭锁开始执行。

      栅栏:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。利用栅栏,可以使线程相互等待,直到所有线程都到达某一点,然后栅栏将打开,所有线程将通过栅栏继续执行。CyclicBarrier支持一个可选的 Runnable 参数,当线程通过栅栏时,runnable对象将被调用。构造函数CyclicBarrier(int parties, Runnable barrierAction),当线程在CyclicBarrier对象上调用await()方法时,栅栏的计数器将增加1,当计数器为parties时,栅栏将打开。

      区别:闭锁用于所有线程等待一个外部事件的发生;栅栏则是所有线程相互等待,直到所有线程都到达某一点时才打开栅栏,然后线程可以继续执行。

    闭锁示例:

      有五个人,一个裁判。这五个人同时跑,裁判开始计时,五个人都到终点了,裁判喊停,然后统计这五个人从开始跑到最后一个撞线用了多长时间。

    import java.util.concurrent.CountDownLatch;
    
    public class Race {
    
        public static void main(String[] args) {
            final int num = 5;
            final CountDownLatch begin = new CountDownLatch(1);
            final CountDownLatch end = new CountDownLatch(num);
    
            for (int i = 0; i < num; i++) {
                new Thread(new AWorker(i, begin, end)).start();
            }
    
            // judge prepare...
            try {
                Thread.sleep((long) (Math.random() * 5000));
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
    
            System.out.println("judge say : run !");
            begin.countDown();
            long startTime = System.currentTimeMillis();
    
            try {
                end.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                long endTime = System.currentTimeMillis();
                System.out.println("judge say : all arrived !");
                System.out.println("spend time: " + (endTime - startTime));
            }
    
        }
    }
    class AWorker implements Runnable {
        final CountDownLatch begin;
        final CountDownLatch end;
        final int id;
    
        public AWorker(final int id, final CountDownLatch begin,
                       final CountDownLatch end) {
            this.id = id;
            this.begin = begin;
            this.end = end;
        }
    
        @Override
        public void run() {
            try {
                System.out.println(this.id + " ready !");
                begin.await();
                // run...
                Thread.sleep((long) (Math.random() * 10000));
            } catch (Throwable e) {
                e.printStackTrace();
            } finally {
                System.out.println(this.id + " arrived !");
                end.countDown();
            }
        }
    
    }

    栅栏示例:

      还是这五个人(这五个人真无聊..),这次没裁判。规定五个人只要都跑到终点了,大家可以喝啤酒。但是,只要有一个人没到终点,就不能喝。 这里也没有要求大家要同时起跑(当然也可以,加latch)。

    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    public class Beer {
    
        public static void main(String[] args) {
            final int count = 5;
            final CyclicBarrier barrier = new CyclicBarrier(count, new Runnable() {
                @Override
                public void run() {
                    System.out.println("drink beer!");
                }
            });
    
            // they do not have to start at the same time...
            for (int i = 0; i < count; i++) {
                new Thread(new Worker(i, barrier)).start();
            }
        }
    
    }
    
    class Worker implements Runnable {
        final int id;
        final CyclicBarrier barrier;
    
        public Worker(final int id, final CyclicBarrier barrier) {
            this.id = id;
            this.barrier = barrier;
        }
    
        @Override
        public void run() {
            try {
                System.out.println(this.id + "starts to run !");
                Thread.sleep((long) (Math.random() * 10000));
                System.out.println(this.id + "arrived !");
                this.barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    我爱Java系列之---【SpringBoot打成war包部署】
    279. Perfect Squares
    矩阵dfs--走回路
    112. Path Sum
    542. 01 Matrix
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    Invert Binary Tree
    563 Binary Tree Tilt
    145 Binary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/jing99/p/11318812.html
Copyright © 2011-2022 走看看