Java多线程(十五):CountDownLatch,Semaphore,Exchanger,CyclicBarrier,Callable和Future

CountDownLatch用来使一个线程或多个线程等待到其他线程完成。CountDownLatch有个初始值count,await方法会阻塞线程,直到通过countDown方法调用使count减少为0才会执行await方法后面的代码。
示例代码
MyThread50_0是WorkThread,不同的线程休眠时间不一样。

public class MyThread50_0 extends Thread { private CountDownLatch cdl; private int sleepSecond; public MyThread50_0(String name, CountDownLatch cdl, int sleepSecond) { super(name); this.cdl = cdl; this.sleepSecond = sleepSecond; } public void run() { try { System.out.println(this.getName() + "启动了,时间为" + new Date()); Thread.sleep(sleepSecond * 1000); cdl.countDown(); System.out.println(this.getName() + "执行完了,时间为" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } } }

MyThread50_1是DoneThread和main方法

public class MyThread50_1 extends Thread { private CountDownLatch cdl; public MyThread50_1(String name, CountDownLatch cdl) { super(name); this.cdl = cdl; } public void run() { try { System.out.println(this.getName() + "要等待了, 时间为" + new Date()); cdl.await(); System.out.println(this.getName() + "等待完了, 时间为" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { CountDownLatch cdl = new CountDownLatch(3); MyThread50_1 dt0 = new MyThread50_1("DoneThread1", cdl); MyThread50_1 dt1 = new MyThread50_1("DoneThread2", cdl); dt0.start(); dt1.start(); MyThread50_0 wt0 = new MyThread50_0("WorkThread1", cdl, 2); MyThread50_0 wt1 = new MyThread50_0("WorkThread2", cdl, 3); MyThread50_0 wt2 = new MyThread50_0("WorkThread3", cdl, 4); wt0.start(); wt1.start(); wt2.start(); } }

运行结果如下

DoneThread2要等待了, 时间为Sun Sep 22 21:37:57 CEST 2019 DoneThread1要等待了, 时间为Sun Sep 22 21:37:57 CEST 2019 WorkThread3启动了,时间为Sun Sep 22 21:37:57 CEST 2019 WorkThread2启动了,时间为Sun Sep 22 21:37:57 CEST 2019 WorkThread1启动了,时间为Sun Sep 22 21:37:57 CEST 2019 WorkThread1执行完了,时间为Sun Sep 22 21:37:59 CEST 2019 WorkThread2执行完了,时间为Sun Sep 22 21:38:00 CEST 2019 WorkThread3执行完了,时间为Sun Sep 22 21:38:01 CEST 2019 DoneThread2等待完了, 时间为Sun Sep 22 21:38:01 CEST 2019 DoneThread1等待完了, 时间为Sun Sep 22 21:38:01 CEST 2019

“DoneThreadX要等待了”和“WorkThreadX启动了”的顺序是随机的。
“WorkThreadX执行完了“的顺序按照1、2、3,因为我们的等待时间2、3、4秒。
待WorkThread3执行完了,才会执行await()之后的代码,DoneThreadX执行完了,同样该顺序随机。
这是一种加强版的等待/通知模型,它可以实现多个工作线程完成任务后通知多个等待线程开始工作。
我们之前的等待/通知模型只能实现一个工作线程完成任务后通知一个等待线程或者所有等待线程开始工作。

Semaphore

Semaphore用来控制并发数量,Semaphore构造函数传入permit(许可),一个permit相当于一个不可重入锁,acquire方法获得permit,relase方法归还permit。
代码示例如下

public class MyThread51 { public static void main(String[] args) { final Semaphore semaphore = new Semaphore(5); Runnable runnable = new Runnable() { public void run() { try { semaphore.acquire(); System.out.println(Thread.currentThread().getName() + "获得了permit,时间为" + new Date()); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + "释放了permit,时间为" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } } }; Thread[] threads = new Thread[10]; for (int i = 0; i < threads.length; i++) threads[i] = new Thread(runnable); for (int i = 0; i < threads.length; i++) threads[i].start(); } }

运行结果如下

Thread-2获得了permit,时间为Sun Sep 29 21:47:05 CEST 2019 Thread-3获得了permit,时间为Sun Sep 29 21:47:05 CEST 2019 Thread-4获得了permit,时间为Sun Sep 29 21:47:05 CEST 2019 Thread-1获得了permit,时间为Sun Sep 29 21:47:05 CEST 2019 Thread-0获得了permit,时间为Sun Sep 29 21:47:05 CEST 2019 Thread-3释放了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-1释放了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-0释放了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-2释放了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-4释放了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-5获得了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-7获得了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-6获得了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-9获得了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-8获得了permit,时间为Sun Sep 29 21:47:07 CEST 2019 Thread-5释放了permit,时间为Sun Sep 29 21:47:09 CEST 2019 Thread-8释放了permit,时间为Sun Sep 29 21:47:09 CEST 2019 Thread-9释放了permit,时间为Sun Sep 29 21:47:09 CEST 2019 Thread-6释放了permit,时间为Sun Sep 29 21:47:09 CEST 2019 Thread-7释放了permit,时间为Sun Sep 29 21:47:09 CEST 2019

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzydgj.html