• java基础系列(八):Semphore,CountDownLatch和CyclicBarrier的使用


    一,Semphore的使用

          信号量主要有两个作用,一个是用于多个共享资源的互斥使用,另一个用于并发线程数控制。

      (1)通过acquire()获取一个信号量,计数器减一,信号量为0,线程进入阻塞等待状态。

      

       (2)通过realease()释放一个信号量,计数器加一,如果有等待的线程则唤醒。

      

       (3)实战

       public static void main(String[] args) {
            Semaphore semaphore = new Semaphore(3);
            for (int i = 0; i < 5; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            semaphore.acquire();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+" 获取到了");
                        try {
                            Thread.sleep(2000);
                            System.out.println(Thread.currentThread().getName());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } finally {
                            semaphore.release();
                        }
    
                    }
                }).start();
            }
    }
    //运行结果

    Thread-0 获取到了
    Thread-1 获取到了
    Thread-2 获取到了
    Thread-1
    Thread-2
    Thread-3 获取到了
    Thread-0
    Thread-4 获取到了
    Thread-3 // 这两个线程获取信号量的时候为0,所以需要等其他线程执行完毕才会执行
    Thread-4 //

    二,CountDownLatch的使用

          当计数器的值为0时,调用await()方法的线程才会被唤醒,继续往下执行。可用于控制让一个线程在指定线程数的线程执行完毕之后接着执行。

     (1)countDown()方法调用之后,计数器减一,最小为0。

       (2)await()被调用之后,线程阻塞直到计数器的值为0。

      (3)实战

        public static void main(String[] args) {
            CountDownLatch countDownLatch = new CountDownLatch(3);
            for (int i = 0; i < 4; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
    
                        System.out.println(Thread.currentThread().getName());
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        countDownLatch.countDown();
    
                    }
                }).start();
            }
            try {
                countDownLatch.await();
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    //运行结果

    Thread-0
    Thread-1
    Thread-2
    Thread-3
    2
    1
    0
    main //当三个线程执行完毕之后,main才会执行;并且计数器的值最小是为0
    0

    三,CyclicBarrier的使用

      所有的线程都到达await()方法之后, 统一往下执行。

      (1)await()方法线程阻塞,计数器为0,开始运行。

      (2)reset()方法重置计数器的值

       (3)实战

        public static void main(String[] args) {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
            for (int i = 0; i <3 ; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            System.out.println(Thread.currentThread().getName()+" 到达状态");
                            cyclicBarrier.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+
                                " 开始执行");
                    }
                }).start();
    
            }
    
    
        }
    //运行结果

    Thread-0 到达状态
    Thread-1 到达状态
    Thread-2 到达状态
    Thread-0 开始执行
    Thread-2 开始执行
    Thread-1 开始执行

      (4)CyclicBarrier和CountDownLatch的区别

         CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的;CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。

     
  • 相关阅读:
    ThinkPHP框架被爆任意代码执行漏洞
    thinkphp session 跨域问题解决方案
    网摘地址
    thinkphp的各种内部函数 D()、F()、S()、C()、L()、A()、I()详解
    IP相关(近两天的学习总结)
    ThinkPHP 手册摘录之(跨模块)调用
    c#让程序在WIN7下兼容模式运行
    QT学习之经典控件源码(如此强大)
    C#自定义控件七水波纹
    C#自定义控件五报警按钮
  • 原文地址:https://www.cnblogs.com/amazing-eight/p/13690371.html
Copyright © 2020-2023  润新知