Java并发编程知识点总结(二十二)——各种并发工具类详解

(一)、CountDownLatch

CountDownLatch其实就是一个计数器,应用场景主要是在线程之间的等待上面。
举个简单的例子:假设学校规定必须全部的学生到齐,老师才能上课。老师首先来到教室,这时班上的同学都还没有来,老师设置计数器为50,进行逐一倒数,并执行等待方法await()。然后同学们相继到达教室,计数器的值也就一直在递减。最后,全班同学都到达了,那么计数器也就减为0了,这时老师就无需等待了,可以继续执行任务。
CountDownLatch的方法并不多,只有如下几个方法:

方法 功能
CountDownLatch(int count) 构造方法,设置计数器的初始值
await() 等待方法,等待计数器减为0
await(long timeout, TimeUnit unit) 限时等待,如果超过一定时间就不再等待
countDown() 计数器数目-1
getCount() 获得计数器的数值

下面举出一个具体的实例:

public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(10);
        Thread thread = new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < 10; i++) {
                    System.out.println("学生" + (i+1) + "到达教室");
                    countDownLatch.countDown();
                }
            }
        };

        System.out.println("老师到达教室");
        thread.start();
        try {
            countDownLatch.await();
            System.out.println("学生到齐,开始上课");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

Java并发编程知识点总结(二十二)——各种并发工具类详解_第1张图片

(二)、CyclicBarrier

CyclicBarrier可以理解为一个循环栅栏,其实和CountDownLatch有一定的相同点。就是都是需要进行计数,CyclicBarrier是等待所有人都准备就绪了,才会进行下一步。不同点在于,CyclicBarrier结束了一次计数之后会自动开始下一次计数。而CountDownLatch只能完成一次。
下面来举个简单的例子: 例如一个军队上战场打仗,出征前需要集合报数。假设总共有10个士兵,依次报数,当10个士兵都报完数了,才能出征。
下面是CyclicBarrier中的一些主要方法:

方法 功能
await() 等待方法
await(long timeout, TimeUnit unit) 限时等待方法
isBroken() 查看等待的线程是否被中断
reset() 重置栅栏,如果有线程在等待会抛出BrokenBarrierException
getNumberWaiting() 查看当前有多少个线程在等待

下面是一个简单的例子进行运用:

public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
        System.out.println("队长:准备出征,全员报数");

        for (int i = 0; i < 9; i++) {
            Thread thread = new Thread() {
                @Override
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getId()+"到!");
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();
        }
        cyclicBarrier.await();
        System.out.println("全员到齐,出发");

    }

Java并发编程知识点总结(二十二)——各种并发工具类详解_第2张图片

(三)、Semaphore

Semaphore主要是用来控制资源数量的工具,可以理解为信号量。初始化时给定信号量的个数,其他线程可以来尝试获得许可,当完成任务之后需要释放响应的许可。
同样我们来举个例子: 我们去银行办理业务通常都需要填表,而银行通常会放置几支笔。当时办理业务的人数肯定是多于笔的总数的。我们就可以这样理解,这几只笔就相当于信号量,排在前面的人可以先获得许可,用完笔之后,就需要把笔还回去,相当于释放许可。

方法 功能
Semaphore(int permits) 构造方法,给定许可证的个数
acquire() 尝试获得一个许可
acquire(int permits) 尝试获得多个许可
release() 尝试释放许可
release(int permits) 尝试释放多个许可

下面展示一个简单的例子:

public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(5);
        for(int i = 0; i < 10 ; i++) {
            Thread thread = new Thread() {
                @Override
                public void run() {
                    try {
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getId()+"获得笔");
                        Thread.sleep(500);
                        System.out.println(Thread.currentThread().getId()+"用完笔");
                        semaphore.release();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();
        }
    }

Java并发编程知识点总结(二十二)——各种并发工具类详解_第3张图片
可以看到,最多的时候只有5个人获得笔,这就是限制了资源的使用。

你可能感兴趣的:(Java高并发)