1、CountDownLatch:减法计数器
代码实例
public class CountDownLatchTest { public static void main(String[] args) { //优先执行,执行完毕之后,才能执行 main //1、实例化计数器,100 CountDownLatch countDownLatch = new CountDownLatch(100); new Thread(()->{ for (int i = 0; i < 100; i++) { System.out.println("++++++++++Thread"); countDownLatch.countDown(); } }).start(); //2、调用 await 方法 让主线程等待countdonwn运行完毕 try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 100; i++) { System.out.println("main--------------"); } } }
countDown() 计数器减一
await() 计数器停止,唤醒其他线程
new CountDownLatch(100)、coutDown()、await() 必须配合起来使用,创建对象时赋的值是多少,coutDown() 就要执行多少次,否则计数器不会清零,计数器就不会停止后,其他线程无法唤醒。
2、CyclicBarrier:加法计数器
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierTest { public static void main(String[] args) { //定义一个计数器,当计数器的值累加到10,输出"放行" CyclicBarrier cyclicBarrier = new CyclicBarrier(30,()->{ System.out.println("放行"); }); for (int i = 1; i <= 90; i++) { final int temp = i; new Thread(()->{ System.out.println("-->"+temp); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }).start(); } } }
await() 执行 CyclicBarrier 的业务,CyclicBarrier 中的 Runnable 执行一次之后,计数器清零,等待下一次执行。
3、Semaphore:计数信号量
实际开发中主要用来做限流操作,即限制可以访问某些资源的线程数量。
-
初始化
-
获取许可
-
释放许可
import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class SemaphoreTest { public static void main(String[] args) { //同时只能进5个人 Semaphore semaphore = new Semaphore(5); for (int i = 0; i < 15; i++) { new Thread(()->{ try { //获得许可 semaphore.acquire(); System.out.println(Thread.currentThread().getName()+"进店购物"); TimeUnit.SECONDS.sleep(5); System.out.println(Thread.currentThread().getName()+"出店"); } catch (InterruptedException e) { e.printStackTrace(); }finally { //释放许可 semaphore.release(); } },String.valueOf(i)).start(); } } } acquire():等待
获取许可,如果没有名额,则等待。
release():释放许可,并且唤醒等待的线程。