JUC并发包:CountDownLatch、CyclicBarrier、Semaphore使用


1.CountDownLatch

让一些线程堵塞直到另一个线程完成一系列操作后才被唤醒。CountDownLatch 主要有两个方法,当一个或多个线程调用 await 方法时,调用线程会被堵塞,其他线程调用 countDown 方法会将计数减一(调用 countDown 方法的线程不会堵塞),当计数其值变为零时,因调用 await 方法被堵塞的线程会被唤醒,继续执行。


案例:

假设有这么一个场景,教室里有班长其他6个人在教室上自习,怎么保证班长等其他6个人都走出教室在把教室门给关掉。

package com.juc.interview;

import java.util.concurrent.CountDownLatch;

/**
 * @description: juc下的类学习
 * @author: Mr.Li
 * @create: 2019-09-29 21:25
 **/
public class CountDownLatchDemo {
    public static void main(String[] args) {
        
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                countDownLatch.countDown();
                System.out.println(Thread.currentThread().getName() + "离开了教室");
            }, String.valueOf(i)).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("班长把门关上了...");
    }

    
}

运行结果:

1离开了教室
2离开了教室
4离开了教室
5离开了教室
3离开了教室
6离开了教室
班长把门关上了...

Process finished with exit code 0

 

2.CyclicBarrier

字面意思是可循环(Cyclic)使用的屏障(Barrier)。他要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法。

案例:

我们假设有这么一个场景,每辆车只能坐4个人,当车满了,就发车。

package com.juc.interview;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @description: CyclicBarrier学习
 * @author: Mr.Li
 * @create: 2019-09-29 21:57
 **/
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4, ()->{
            System.out.println("车满了,开始发车");
        });

        for (int i = 1; i <= 8; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "成功上车");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}


运行结果:

1成功上车
2成功上车
4成功上车
5成功上车
车满了,开始发车
7成功上车
3成功上车
8成功上车
6成功上车
车满了,开始发车

Process finished with exit code 0


 

3.Semaphore

信号量主要用于两个目的,一个是用于多个共享资源的互斥作用,另一个用于并发线程数的控制

 

案例:

假设我们有 3 个停车位,6 辆车去抢
 

package com.juc.interview;

import java.util.concurrent.Semaphore;

/**
 * @description: SemaphoreDemo学习
 * @author: Mr.Li
 * @create: 2019-09-29 22:07
 **/
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);
        for (int  i  = 1; i <= 6; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()  + "抢到车位");
                    Thread.sleep(3000);
                    System.out.println(Thread.currentThread().getName() + "离开车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }

            }).start();
        }
    }
}


运行结果:

Thread-0抢到车位
Thread-2抢到车位
Thread-1抢到车位
Thread-2离开车位
Thread-0离开车位
Thread-1离开车位
Thread-4抢到车位
Thread-3抢到车位
Thread-5抢到车位
Thread-3离开车位
Thread-4离开车位
Thread-5离开车位

Process finished with exit code 0


每日一言:

人生就像射箭,而梦想就像箭靶子,如果你连箭靶子都找不到的话,那每天的拉弓就毫无意义

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章