您的位置 首页 java

Java,倒计时门栓,信号量(Semaphore),循环栅栏(CyclicBarrier)

概念

倒计时门栓————一种灵活的闭锁实现

闭锁 ,延迟 线程 的进度直到其到达终止状态,在完成某些运算时,只有其他所有线程的运算全部完成,当前运算才继续执行,就是闭锁。

倒计时门栓CountDownLatch, 主要用于不同角色线程间的同步。例如:在裁判/运动员模式中,裁判线程让多个运动员线程同时开始,也可以用于协调主从线程,让主线程等待多个从线程的结果。

信号量 ————用于限制对资源的并发访问数

semaphore (信号量), 是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。

Semaphore一般用于流量的控制,特别是公共资源有限的应用场景。例如:数据库的连接,假设数据库的连接数上线为10个,多个线程并发操作数据库可以使用Semaphore来控制并发操作数据库的线程个数最多为10个。

循环栅栏————一组线程相互等待,达到某个共同点

循环栅栏(CyclicBarrier) ,用于同一角色线程间的协调一致,所有线程在到达栅栏后都需要等待其他线程,等所有线程都到达后再一起通过,它是循环的,可以用作重复的同步。

到达屏障,等待直到所有的参与者在此屏障上调用await,返回值:当前线程的到达索引,0表示最后一个到达;

屏障被打破,是指调用breakBarrier方法把broken被置为true,线程被中断、barrierCommand任务执行失败、超时、调用reset方法都会打破屏障。

复位屏障,将屏障重置为其初始状态。如果任何一方当前正在等待障碍,他们将抛出BrokenBarrier Exception

代码案例

倒计时门栓————一种灵活的闭锁实现,案例

 import  java .util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * 闭锁
 */public class ThreadLatchDemo {

    /**
     * @param args
     */    public  static   void  main(String[] args) {
        // 声明,等待事件数量9次
        CountDownLatch countDownLatch = new CountDownLatch(9);
        // 依次创建并启动处于等待状态的5个MyRunnable线程
        for (int i = 1; i <= 9; ++i) {
            new Thread(new MyRunnable(countDownLatch, i)).start();
        }
        System.out.println("等待线程开始工作......");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程执行完毕!");
    }

    public static class MyRunnable implements Runnable {

         private  final CountDownLatch countDownLatch;
        private final int num;

        public MyRunnable(CountDownLatch countDownLatch, int num) {
            this.countDownLatch = countDownLatch;
            this.num = num;
        }

        public void run() {
            try {
                Thread.sleep(new Random().nextInt(2000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程:" + num + ",执行完毕.");
            // 当前事件执行完毕,计数 -1
            countDownLatch.countDown();
        }
    }

}  

信号量————用于限制对资源的并发访问数,案例

 import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class ThreadSemaphoreDemo {

    public static void main(String[] args) {
        // 信号量,同时最大允许3个线程同时执行
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i <= 9; i++) {
            new Thread(new MyRunnable(semaphore, i)).start();
        }
    }

    public static class MyRunnable implements Runnable {

        private final Semaphore semaphore;
        private final int num;

        public MyRunnable(Semaphore semaphore, int num) {
            this.semaphore = semaphore;
            this.num = num;
        }

        public void run() {
            try {
                //获取许可
                semaphore.acquire();
                System.out.println("线程:" + num + ",开始执行了!");
                TimeUnit.SECONDS.sleep(2);
                System.out.println("线程:" + num + ",执行完成了!");
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}  

循环栅栏————一组线程相互等待,达到某个共同点,案例

 import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class ThreadCyclicBarrierDemo {

    /**
     * @param args
     */    public static void main(String[] args) {
        //
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        // 依次创建并启动处于等待状态的线程
        for (int i = 1; i <= 3; ++i) {
            new Thread(new MyRunnable(cyclicBarrier, i)).start();
        }
        System.out.println("等待线程开始工作......");
        System.out.println("主线程,结束!");
    }

    public static class MyRunnable implements Runnable {

        private final CyclicBarrier cyclicBarrier;
        private final int num;

        public MyRunnable(CyclicBarrier cyclicBarrier, int num) {
            this.cyclicBarrier = cyclicBarrier;
            this.num = num;
        }

        public void run() {
            System.out.println("线程" + num + ",开始.");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println("线程:" + num + ",一起来做.");
            try {
                Thread.sleep(new Random().nextInt(2000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程:" + num + ",执行完毕.");
        }
    }

}  

文章来源:智云一二三科技

文章标题:Java,倒计时门栓,信号量(Semaphore),循环栅栏(CyclicBarrier)

文章地址:https://www.zhihuclub.com/185792.shtml

关于作者: 智云科技

热门文章

网站地图