【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
2017-01-07 21:26
926 查看
前言
JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch、CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行介绍。CountDownLatch
CountDownLatch的主要作用是利用计数来保证线程的执行顺序(我自己的理解),有点像倒计时,当计数为0时某个线程才能开始执行。CountDownLatch的主要方法很简单易用,包括:
CountDownLatch(int count) : 构造方法,需要传入计数的初始值
void await() : 调用者线程会被挂起,直到计数为0时才能执行
boolean await(long timeout, TimeUnit unit) : 同上,但是加入了超时参数,如果超时了计数还不为0,也会照样执行,避免了一直阻塞
void countDown() : 计数减一
示例代码:CountDownLatchTest.java
package juc.util; import java.util.concurrent.CountDownLatch; /** * Created by puyangsky on 2017/1/7. */ public class CountDownLatchTest { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(2); //用了匿名类创建线程 new Thread() { public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(2000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕"); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); new Thread() { public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(2000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕"); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); System.out.println("主线程"+Thread.currentThread().getName()+"正在执行"); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("主线程"+Thread.currentThread().getName()+"执行完毕"); } }
结果:
主线程main正在执行 子线程Thread-0正在执行 子线程Thread-1正在执行 子线程Thread-0执行完毕 子线程Thread-1执行完毕 主线程main执行完毕
可以从结果中看到主线程本来是最先执行完,结果需要等两个子线程执行完才结束,就是因为调用了await方法。
CyclicBarrier
CyclicBarrier的意思是回环栅栏,作用是让一组线程同时到达某个时间节点。提供的重要方法如下:CyclicBarrier(int parties) : 构造方法,传入线程组的数量
CyclicBarrier(int parties, Runnable barrierAction) : 构造方法,传入线程组的数量和当线程达到时间节点后要做的操作(由其中的某一个线程去执行)
int await() : 挂起当前线程,直到所有线程组中的线程都完成后继续执行,返回当前线程到达的次序
int await(long timeout, TimeUnit unit) : 加了一个超时参数
示例代码 CyclicBarrierTest.java:
package juc.util; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * Created by puyangsky on 2017/1/7. */ public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() { @Override public void run() { System.out.println("当前线程"+Thread.currentThread().getName()); } }); for (int i=0;i<5;i++) { new Task(barrier).start(); } } static class Task extends Thread { private CyclicBarrier barrier; public Task(CyclicBarrier barrier) { this.barrier = barrier; } public void run() { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); try { Thread.sleep(3000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完成"); barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println("全部线程执行完成"); } } }
结果:
子线程Thread-0正在执行 子线程Thread-3正在执行 子线程Thread-2正在执行 子线程Thread-1正在执行 子线程Thread-4正在执行 子线程Thread-3执行完成 子线程Thread-2执行完成 子线程Thread-0执行完成 子线程Thread-1执行完成 子线程Thread-4执行完成 当前线程Thread-4 全部线程执行完成 全部线程执行完成 全部线程执行完成 全部线程执行完成 全部线程执行完成
可以看到这一组线程是同步的去执行的。
Semaphore
Semaphore的意思是信号量,其作用是提供一个许可范围,只有获得了许可才能继续执行。Semaphore(int permits):构造方法,需要传入许可数
Semaphore(int permits, boolean fair):fair为true时使用公平锁,false时使用非公平锁,具体在介绍AQS时讲解
void acquire():获得许可,可中断
void acquireUninterruptibly():不可中断的获取
void release():释放许可
示例 SemaphoreTest.java
package juc.util; import java.util.concurrent.Semaphore; /** * Created by puyangsky on 2017/1/7. */ public class SemaphoreTest { public static void main(String[] args) { Semaphore semaphore = new Semaphore(5); for (int i = 0;i < 10;i++) { new Worker(i, semaphore).start(); } } static class Worker extends Thread { private Semaphore semaphore; private int num; public Worker(int num, Semaphore semaphore) { this.semaphore = semaphore; this.num = num; } public void run() { try { semaphore.acquire(); System.out.println("工人" + (this.num + 1) + "占用一个机器在生产..."); Thread.sleep(2000); System.out.println("工人" + (this.num + 1) + "释放一个机器..."); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } } }
结果
工人1占用一个机器在生产... 工人3占用一个机器在生产... 工人4占用一个机器在生产... 工人5占用一个机器在生产... 工人7占用一个机器在生产... 工人1释放一个机器... 工人5释放一个机器... 工人4释放一个机器... 工人7释放一个机器... 工人3释放一个机器... 工人8占用一个机器在生产... 工人9占用一个机器在生产... 工人10占用一个机器在生产... 工人6占用一个机器在生产... 工人2占用一个机器在生产... 工人9释放一个机器... 工人6释放一个机器... 工人10释放一个机器... 工人8释放一个机器... 工人2释放一个机器...
可以看到每次只有五个线程能运行,其他线程只有等待这五个线程释放许可后才能运行。
参考文章:
Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
jdk1.7
相关文章推荐
- Java多线程之同步工具类(CountDownLatch、CyclicBarrier、Semaphore)
- 第8章 Java中的并发工具类(CountDownLatch CyclicBarrier Semaphore Exchanger)
- Java多线程——同步器 Semaphore、 CountDownLatch、 CyclicBarrier 、Exchanger
- Java并发:同步工具类详解(CountDownLatch、CyclicBarrier、Semaphore)
- Java并发编程之2——同步工具类的使用(CountDownLatch,CyclicBarrier,BlockungQueue,Semaphore)
- 【Java多线程】CountDownLatch、CyclicBarrier和Semaphore使用
- java多线程 关于synchronized wait notify CountDownLatch CyclicBarrier Semaphore
- Java中的并发工具类:CountDownLatch、CyclicBarrier和Semaphore
- Java多线程(八)之Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- Java多线程:CountDownLatch、CyclicBarrier 和 Semaphore
- Java多线程之CountDownLatch、CyclicBarrier和Semaphore
- Java多线程(八)之Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- Java多线程:CountDownLatch、CyclicBarrier 和 Semaphore
- 多线程编程的常用类(CountDownLatch, Semaphore, CyclicBarrier 和 Exchanger)
- 《Java 7 并发编程指南》学习概要 (3)Semaphore, CountDownLatch, CyclicBarrier , Phaser, Exchanger
- Java并发之CountDownLatch、CyclicBarrier和Semaphore
- Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- Java并发: CountDownLatch、CyclicBarrier和Semaphore
- Java并发之CountDownLatch、CyclicBarrier和Semaphore
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore