java多线程快速入门(二十一)
CountDownLatch(闭锁)计数器
有一个任务A,它要等待其他4个任务执行完毕之后才执行,此时就可以利用CountDownLatch来实现这种功能
package com.cppdy; import java.util.concurrent.CountDownLatch; class MyThread17 extends Thread{ private CountDownLatch countdownlatch; public MyThread17(CountDownLatch countdownlatch) { this.countdownlatch=countdownlatch; } @Override public void run() { try { sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName()+"线程执行完毕"); countdownlatch.countDown(); } } public class ThreadDemo17 { public static void main(String[] args) throws Exception { CountDownLatch cd=new CountDownLatch(2); MyThread17 my1 = new MyThread17(cd); MyThread17 my2 = new MyThread17(cd); my1.start(); my2.start(); Thread.sleep(300); cd.await(); System.out.println("主线程结束"); } }
CyclicBarrier(回环栅栏)
CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到这个数目时,所有进入等待状态的线程被唤醒并继续
package com.cppdy; import java.util.concurrent.CyclicBarrier; class MyThread18 extends Thread { private CyclicBarrier cyclicBarrier; public MyThread18(CyclicBarrier cyclicBarrier) { this.cyclicBarrier = cyclicBarrier; } @Override public void run() { System.out.println("开始执行线程"); try { sleep(2000); //第一次进来,表示有一个线程等待,还不满足三个,不释放 //第二次进来,也不满足 //第三次进来,满足了,就继续执行下面的代码 cyclicBarrier.await(); } catch (Exception e) { e.printStackTrace(); } System.out.println("结束执行线程"); } } public class ThreadDemo18 { public static void main(String[] args) throws Exception { CyclicBarrier cb = new CyclicBarrier(3); MyThread18 my1 = new MyThread18(cb); MyThread18 my2 = new MyThread18(cb); MyThread18 my3 = new MyThread18(cb); my1.start(); my2.start(); my3.start(); System.out.println("主线程执行结束"); } }
Semaphore(信号量)
Semaphore是一种基于计数的信号量,它可以设置一个阀值,多个线程竞争获取许可信号,做自己的申请后归还,超过阀值后,线程申请许可信号将会被阻塞
package com.cppdy; import java.util.Random; import java.util.concurrent.Semaphore; class MyThread19 extends Thread { private String name; private Semaphore sp; public MyThread19(String name, Semaphore sp) { this.name = name; this.sp = sp; } @Override public void run() { int availablePermits = sp.availablePermits(); if (availablePermits > 0) { System.out.println(name + ",好开心啊,居然还有坑"); } else { System.out.println(name + ",好伤心啊,怎么没有坑了"); } try { sp.acquire(); System.out.println(name + ",好开心啊,终于抢到啦"); //模拟上厕所时间 Thread.sleep(new Random().nextInt(1000)); System.out.println(name + ",好爽啊,终于上完啦"); sp.release(); } catch (Exception e) { e.printStackTrace(); } } } public class ThreadDemo19 { public static void main(String[] args) throws Exception { Semaphore sp = new Semaphore(3); for (int i = 0; i < 10; i++) { MyThread19 mt = new MyThread19("第" + i + "个人", sp); mt.start(); } } }