Java 的CountDownLatch,CyclicBarrier,semaphore

信号量类semaphore 主要应用

1,信号量参数为1个,那么相当于snychorized 同步机制

2,配合线程池使用,例如一个厕所只有五个位置,现在门口有五十个人排队,那么相当于要处理50个线程调用,每次最多有5个并发,而且这个调用过程相对于比较短,有的是小便哦,所以我们可以初始化一个线程池进行处理,

CountDownLatch 应用场景,比如短跑跑步,要等十位选手全部到位才开枪!选手准备相当于一个线程的执行完毕,要等十个线程都执行完毕再执行下面的操作!

CyclicBarrier 应用场景:同样是短跑跑步,十个选手准备好,等待枪声响了一起跑!选手开始跑才是一个线程执行完毕,而等待的状态相当于线程的await状态!!!


ExecutorService service=Executors.newCachedThreadPool();

final Semaphore sp = new Semaphore(5);

 for(int i=0;i<50;i++){ Runnable runnable = new Runnable(){ public void run(){ try { sp.acquire(); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("线程" + Thread.currentThread().getName() + "进入,当前已有" + (3-sp.availablePermits()) + "个并发"); try { Thread.sleep((long)(Math.random()*10000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程" + Thread.currentThread().getName() + "即将离开"); sp.release(); //下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元 System.out.println("线程" + Thread.currentThread().getName() + "已离开,当前已有" + (3-sp.availablePermits()) + "个并发"); } }; service.execute(runnable); }



Semaphore作为互斥锁使用: 当信号量初始化为 1,使得它在使用时最多只有一个可用的许可,从而可用作一个相互排斥的锁。这通常也称为二进制信号量,因为它只能有两种状态:一个可用的许可,或零个可用的许可。按此方式使用时,与传统互斥锁最大不同就是在释放的时候并不是必须要拥有锁的对象释放,也可以由其他的对象释放,因为信号量没有所有权的概念。在某些专门的上下文(如死锁恢复)中这会很有用。 Semaphore的构造方法有两种: 第一种: [java] view plain copy 1.Semaphore(int permits) //用给定的许可数和非公平的公平设置创建一个 Semaphore。 第一种构造方法创建的信号灯,现在在获取的时候是随机的,没有一定的顺序,例如上例中,在前三个线程中的一个运行完毕以后,释放一个信号灯,剩下的两个线程就会随机的一个线程得到这个信号灯而运行。 第二种: [java] view plain copy 1.Semaphore(int permits, boolean fair) //用给定的许可数和给定的公平设置创建一个 Semaphore 第二种构造方法可选地接受一个公平 参数。当设置为 false 时,此类不对线程获取许可的顺序做任何保证。特别地,闯入 是允许的,也就是说可以在已经等待的线程前为调用acquire() 的线程分配一个许可,从逻辑上说,就是新线程将自己置于等待线程队列的头部。当公平设置为 true 时,信号量保证对于任何调用acquire() 方法的线程而言,都按照处理它们调用这些方法的顺序(即先进先出;FIFO)来选择线程、获得许可。注意,FIFO 排序必然应用到这些方法内的指定内部执行点。所以,可能某个线程先于另一个线程调用了acquire(),但是却在该线程之后到达排序点,并且从方法返回时也类似。还要注意,非同步的tryAcquire() 方法不使用公平设置,而是使用任意可用的许可。 通常,应该将用于控制资源访问的信号量初始化为公平的,以确保所有线程都可访问资源。为其他的种类的同步控制使用信号量时,非公平排序的吞吐量优势通常要比公平考虑更为重要。


 •CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行;

 •CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。

对于CountDownLatch来说,重点是“一个线程(多个线程)等待”,而其他的N个线程在完成“某件事情”之后,可以终止,也可以等待。而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程都必须等待。

CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行。

你可能感兴趣的:(Java 的CountDownLatch,CyclicBarrier,semaphore)