1.countDownLatch
减法计数器:实现调用几次线程后,在触发另一个任务
简单代码实现:
举例说明:就像五个人在同一房间里,有一个看门的大爷,当五个人都出去后,他才能锁门,也就是说 执行5次出门这个动作的线程后,才出发了锁门的这个动作
import java.util.concurrent.CountDownLatch; /** * @program: juc * @description * @author: 不会编程的派大星 * @create: 2021-04-24 16:55 **/ public class CountDownLatchTest { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(5); System.out.println("door is open"); for (int i = 1; i <= 5 ; i++) { new Thread(() -> { System.out.println(Thread.currentThread().getName()+" is going out"); countDownLatch.countDown(); },String.valueOf(i)).start(); } countDownLatch.await(); System.out.println("door is closed"); } }
代码运行结果:
基本原理:
countDownLatch.countDown(); // 数量-1
countDownLatch.await(); // 等待计数器归零,然后再向下执行
每次有线程调用 countDown() 数量-1,假设计数器变为0,countDownLatch.await() 就会被唤醒,继续执行!
2.CyclicBarrier
这里我们简单理解为 加法计数器
简单代码实现:
举例说明:这里只要集齐7颗龙珠,就执行 打印 “7颗龙珠集齐了”的线程,这里我们先设置线程计数为8,看看会不会执行打印的线程,然后在执行计数为7的情况
1.cyclicBarrier计数为8的时候,执行线程数量为7的时候:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * @program: juc * @description * @author: 不会编程的派大星 * @create: 2021-04-24 17:31 **/ public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(8,new myThread()); for (int i = 1; i <= 7 ; i++) { int finalI = i; new Thread(() -> { System.out.println(Thread.currentThread().getName()+"收集了"+ finalI+"颗龙珠"); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } },String.valueOf(i)).start(); } } } class myThread implements Runnable{ @Override public void run() { System.out.println("7颗龙珠集齐啦"); } }
执行结果:
2.cyclicBarrier计数为1的时候,执行线程数量为7的时候:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * @program: juc * @description * @author: 不会编程的派大星 * @create: 2021-04-24 17:31 **/ public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7,new myThread()); for (int i = 1; i <= 7 ; i++) { int finalI = i; new Thread(() -> { System.out.println(Thread.currentThread().getName()+"收集了"+ finalI+"颗龙珠"); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } },String.valueOf(i)).start(); } } } class myThread implements Runnable{ @Override public void run() { System.out.println("7颗龙珠集齐啦"); } }
执行结果:
可以看到
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,new myThread());
当执行完7个线程后,才会执行一个实现了Runnable接口的线程
3.Semaphore
简单代码实现:
举例说明:抢车位 ,6个车,最多同时只能有三个车进
import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * @program: juc * @description * @author: 不会编程的派大星 * @create: 2021-04-24 18:26 **/ public class SemaphoreTest { public static void main(String[] args) { //线程数量 ,停车位,,6辆车在等,最多只能同时进来三个 限流 Semaphore semaphore = new Semaphore(3); for (int i = 1; i <= 6 ; i++) { new Thread(() -> { try { semaphore.acquire();//获得 System.out.println(Thread.currentThread().getName()+"抢到车位了"); TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName()+"离开车位了"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); //释放 } },String.valueOf(i)).start(); } } }
运行结果:
原理说明:
semaphore.acquire()
; 获得,假设如果已经满了,等待,等待被释放为止!
semaphore.release()
; 释放,会将当前的信号量释放 + 1,然后唤醒等待的线程!
作用: 多个共享资源互斥的使用!并发限流,控制最大的线程数!
以上就是java多线程JUC常用辅助类详解的详细内容,更多关于java多线程JUC辅助类的资料请关注服务器之家其它相关文章!
原文链接:https://blog.csdn.net/weixin_45827693/article/details/116096664