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


每日一言:

人生就像射箭,而夢想就像箭靶子,如果你連箭靶子都找不到的話,那每天的拉弓就毫無意義

 

 

 

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