JUC中常用的三种辅助类,你知道吗?

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

  1. CountDownLatch
  2. CyclicBarrier
  3. Semaphore

1.CountDownLatch

下图是Jdk1.8中解释的CountDownLatch类功能,简单而言,在实例化时,需要传入一个信号量,每当一个线程执行后,信号量减1,当信号量为0时,释放阻塞的线程。

JUC中常用的三种辅助类,你知道吗?_第1张图片
不管你听懂没,看就完了!

用个小Demo模拟,需求是启动5个线程,当5个线程执行完后,main线程才能继续执行,如果不使用CountDownLatch,线程的调用将不可控。

public static void main(final String[] args) throws InterruptedException {
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t 执行");
        }, String.valueOf(i)).start();
    }
    System.out.println(Thread.currentThread().getName() + "最终执行");
}

JUC中常用的三种辅助类,你知道吗?_第2张图片
可以看出,不使用任何线程控制等方法,线程是随计算机调度的,线程的执行顺序并不是我们预期希望的。

当使用CountDownLatch,实例化时将信号量设置为5,每当一个线程执行后,信号量减1,当5个线程执行完后,信号量为0,main线程才执行。

public static void main(final String[] args) throws InterruptedException {
   //实例化,并传入信号初始量
    CountDownLatch countDownLatch = new CountDownLatch(5);
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t 执行");
            //信号量减1
            countDownLatch.countDown();
        }, String.valueOf(i)).start();
    }
    countDownLatch.await();
    System.out.println(Thread.currentThread().getName() + "最终执行");
}

在这里插入图片描述

2.CyclicBarrier

下图是Jdk1.8中解释的CyclicBarrier类功能,简单而言,在实例化时,需要传入一个信号量和Runnable接口,每当一个线程执行后,信号量加1,当信号量的值达到传入的预期值,则执行方法。

JUC中常用的三种辅助类,你知道吗?_第3张图片
不管你听懂没,看就完了!

这里我们定义了只要达到3个线程,就执行方法。

public static void main(String[] args) {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
        System.out.println("---------方法执行---------");
    });

    for (int i = 0; i < 3; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t执行");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }, String.valueOf(i)).start();
    }
}



3. Semaphore(信号灯)

下图为Jdk1.8文档中的解释,简单来说,在初始化时设定一个预期值,当线程数量达到预期值,其他线程被阻塞,只有当线程使用完毕,其他线程才能重新开始抢占资源。
JUC中常用的三种辅助类,你知道吗?_第4张图片

不管你听懂没,看就完了!

public static void main(String[] args) {
    Semaphore Semaphore = new Semaphore(3);
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            try {
                Semaphore.acquire();
                System.out.println(Thread.currentThread().getName() + "\t抢占到资源");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + "\t释放了资源");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                Semaphore.release();
            }
        }, String.valueOf(i)).start();
    }
}

从运行结果中很容易理解,我们定义了初始值为3,说明只要有3个线程抢占到资源,直到他们释放,其他资源都只能等待。
JUC中常用的三种辅助类,你知道吗?_第5张图片

你可能感兴趣的:(JUC)