第六章-java并发包几个常用类

CountDownLatch

让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒。

两个主要方法:

  • 等待:await()
  • 减1:countDown()

案例:

  1. 班长关门1

    image-20191107105356133

  2. 秦灭六国

    image-20191107105405698

  3. 班长关门2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    /**
    * @desc 倒计时
    * 5个人都走了,才关门?
    * @Author xw
    * @Date 2019/8/9
    */
    public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
    CountDownLatch countDownLatch = new CountDownLatch(5);
    for(int i = 1; i <= 5; i++) { // 5个同学
    new Thread(() -> {
    try {
    System.out.println(Thread.currentThread().getName() + "离开");
    TimeUnit.SECONDS.sleep(1);
    countDownLatch.countDown();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }, "同学[" + i + "]").start();
    }
    countDownLatch.await();
    System.out.println("班长关门");
    }
    }

CyclicBarrier

类似计数器,达到数量才放行。

  1. 计数器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     /**
    * @desc 计数器
    * 5个人都到齐了才出发
    * @Author xw
    * @Date 2019/8/9
    */
    public class CyclicBarrierDemo {
    public static void main(String[] args) {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
    for (int i = 1; i <= 5; i++) {
    new Thread(() -> {
    try {
    System.out.println(Thread.currentThread().getName() + "同学到了");
    try {
    TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    cyclicBarrier.await();
    } catch (InterruptedException e) {
    e.printStackTrace();
    } catch (BrokenBarrierException e) {
    e.printStackTrace();
    }
    }, "T" + i).start();
    }
    while ((cyclicBarrier.getNumberWaiting()+1) != 5) {

    }
    System.out.println("人数到齐准备出发!");
    }
    }
  1. 七颗龙珠

    image-20191107105558800

Semaphore

信号量,两个目的:一个用于多个共享资源的互斥使用,另一个用于并发线程数的控制。

  1. 抢车位1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /**
    * @desc 信号量
    * 停车场(5个车位,20人抢)
    * @Author xw
    * @Date 2019/8/9
    */
    public class SemaphoreDemo {
    public static void main(String[] args) {
    Semaphore semaphore = new Semaphore(5); // 停车场只有5个车位
    for (int i = 1; i <= 20; i++) { // 20个人抢车位
    new Thread(() -> {
    try {
    semaphore.acquire();
    System.out.println(Thread.currentThread().getName() + "》》》》抢到车位");
    try {
    TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "离开了=======");
    } catch (InterruptedException e) {
    e.printStackTrace();
    } finally {
    semaphore.release();
    }
    }, "同学" + i).start();
    }
    }
    }
  1. 抢车位2

    image-20191107105707081