JUC强大的辅助类

梦里梦外; 2022-09-08 00:13 283阅读 0赞

JUC中提供了三种常用的辅助类,通过这些辅助类可以很好的解决线程数量过多时Lock锁的频繁操作。这三种辅助类为:
• CountDownLatch: 减少计数
• CyclicBarrier: 循环栅栏
• Semaphore: 信号灯

CountDownLatch

CountDownLatch类可以设置一个计数器,然后通过countDown方法来进行减1的操作,使用await方法等待计数器不大于0,然后继续执行await方法之后的语句。
• CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞
• 其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞)
• 当计数器的值变为0时,因await方法阻塞的线程会被唤醒,继续执行

场景: 6个同学陆续离开教室后值班同学才可以关门。

  1. package com.dongguo.juc;
  2. import java.util.concurrent.CountDownLatch;
  3. /** * @author Dongguo * @date 2021/8/24 0024-16:03 * @description: CountDownLatch */
  4. public class CountDownLatchDemo {
  5. /** * 6个同学陆续离开教室后值班同学才可以关门 */
  6. public static void main(String[] args) throws Exception {
  7. //定义一个数值为6的计数器
  8. CountDownLatch countDownLatch = new CountDownLatch(6);
  9. // 创建6个同学
  10. for (int i = 1; i <= 6; i++) {
  11. new Thread(() -> {
  12. try {
  13. if (Thread.currentThread().getName().equals("同学6")) {
  14. Thread.sleep(2000);
  15. }
  16. System.out.println(Thread.currentThread().getName() + "离开了"); //计数器减一,不会阻塞
  17. countDownLatch.countDown();
  18. } catch (
  19. Exception e) {
  20. e.printStackTrace();
  21. }
  22. }, "同学" + i).start();
  23. }
  24. //主线程await休息
  25. System.out.println("主线程睡觉");
  26. countDownLatch.await();//主线程被唤醒
  27. //全部离开后自动唤醒主线程
  28. System.out.println("全部离开了,现在的计数器为" + countDownLatch.getCount());
  29. }
  30. }
  31. 运行结果:
  32. 主线程睡觉
  33. 同学1离开了
  34. 同学2离开了
  35. 同学3离开了
  36. 同学4离开了
  37. 同学5离开了
  38. 同学6离开了
  39. 全部离开了,现在的计数器为0

CyclicBarrier

CyclicBarrier看英文单词可以看出大概就是循环阻塞的意思,在使用中CyclicBarrier的构造方法第一个参数是目标障碍数,每次执行CyclicBarrier一次障碍数会加一,如果达到了目标障碍数,才会执行cyclicBarrier.await()之后的语句。可以将CyclicBarrier理解为加1操作
场景: 集齐7颗龙珠就可以召唤神龙

  1. package com.dongguo.juc;
  2. import java.util.concurrent.CyclicBarrier;
  3. /** * @author Dongguo * @date 2021/8/24 0024-16:09 * @description: */
  4. public class CyclicBarrierDemo {
  5. //定义神龙召唤需要的龙珠总数
  6. private final static int NUMBER = 7;
  7. //集齐7颗龙珠就可以召唤神龙
  8. public static void main(String[] args) {
  9. // 定义循环栅栏
  10. CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER, () -> {
  11. System.out.println("集齐" + NUMBER + "颗龙珠,现在召唤神龙!!!!!!!!!");
  12. });
  13. //定义7个线程分别去收集龙珠
  14. for (int i = 1; i <= 7; i++) {
  15. new Thread(() -> {
  16. try {
  17. // if (Thread.currentThread().getName().equals("龙珠3号")) {
  18. // System.out.println("龙珠3号抢夺战开始,孙悟空开启超级赛亚人模式!");
  19. Thread.sleep(5000);
  20. // System.out.println("龙珠3号抢夺战结束,孙悟空打赢了,拿到了龙珠3号!");
  21. // } else {
  22. System.out.println(Thread.currentThread().getName() + "收集到了!!!!");
  23. // }
  24. cyclicBarrier.await();
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }, "龙珠" + i + "号").start();
  29. }
  30. }
  31. }
  32. 运行结果:
  33. 龙珠5号收集到了!!!!
  34. 龙珠3号收集到了!!!!
  35. 龙珠1号收集到了!!!!
  36. 龙珠2号收集到了!!!!
  37. 龙珠4号收集到了!!!!
  38. 龙珠7号收集到了!!!!
  39. 龙珠6号收集到了!!!!
  40. 集齐7颗龙珠,现在召唤神龙!!!!!!!!!

Semaphore

Semaphore的构造方法中传入的第一个参数是最大信号量(可以看成最大线程池),每个信号量初始化为一个最多只能分发一个许可证。使用acquire方法获得许可证,release方法释放许可
场景: 抢车位, 6部汽车3个停车位

  1. package com.dongguo.juc;
  2. import java.util.concurrent.Semaphore;
  3. /** * @author Dongguo * @date 2021/8/24 0024-16:14 * @description: Semaphore */
  4. public class SemaphoreDemo {
  5. /** * 抢车位, 10部汽车3个停车位 */
  6. public static void main(String[] args) throws Exception {
  7. //定义3个停车位
  8. Semaphore semaphore = new Semaphore(3);
  9. //模拟6辆汽车停车
  10. for (int i = 1; i <= 10; i++) {
  11. Thread.sleep(100);
  12. //停车
  13. new Thread(() -> {
  14. try {
  15. System.out.println(Thread.currentThread().getName() + "找车位ing");
  16. semaphore.acquire();
  17. System.out.println(Thread.currentThread().getName() + "汽车停车成功!");
  18. Thread.sleep(3000);//停车时间
  19. } catch (Exception e) {
  20. e.printStackTrace();
  21. } finally {
  22. System.out.println(Thread.currentThread().getName() + "溜了溜了");
  23. semaphore.release();
  24. }
  25. }, "汽车" + i).start();
  26. }
  27. }
  28. }
  29. 运行结果:
  30. 汽车1找车位ing
  31. 汽车1汽车停车成功!
  32. 汽车2找车位ing
  33. 汽车2汽车停车成功!
  34. 汽车3找车位ing
  35. 汽车3汽车停车成功!
  36. 汽车4找车位ing
  37. 汽车5找车位ing
  38. 汽车6找车位ing
  39. 汽车7找车位ing
  40. 汽车8找车位ing
  41. 汽车9找车位ing
  42. 汽车10找车位ing
  43. 汽车1溜了溜了
  44. 汽车4汽车停车成功!
  45. 汽车2溜了溜了
  46. 汽车5汽车停车成功!
  47. 汽车3溜了溜了
  48. 汽车6汽车停车成功!
  49. 汽车4溜了溜了
  50. 汽车7汽车停车成功!
  51. 汽车5溜了溜了
  52. 汽车8汽车停车成功!
  53. 汽车6溜了溜了
  54. 汽车9汽车停车成功!
  55. 汽车7溜了溜了
  56. 汽车10汽车停车成功!
  57. 汽车8溜了溜了
  58. 汽车9溜了溜了
  59. 汽车10溜了溜了

发表评论

表情:
评论列表 (有 0 条评论,283人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JUC强大辅助

    JUC中提供了三种常用的辅助类,通过这些辅助类可以很好的解决线程数量过多时Lock锁的频繁操作。这三种辅助类为: • CountDownLatch: 减少计数 • Cy

    相关 JUC强大辅助工具

    JUC中提供了一些辅助类,通过这些辅助类可以很好的解决线程数量过多时Lock锁的频繁操作。常用的三种辅助类有: • CountDownLatch: 减少计数 • Cycli

    相关 辅助工具

    1:项目管理软件,能随时随地看到项目的进展,以及bug的反馈等等信息 > [http://www.zentao.net/][http_www.zentao.net]  禅道