Java並發之Semaphore的使用


Java並發之Semaphore的使用

一.簡介

  今天突然發現,看着自己喜歡的球隊發揮如此的棒,然后寫着博客,這種感覺很爽。現在是半場時間,就趁着這個時間的空隙,說說Java並發包中另外一個重量級的類Semaphore,這個類從字面意義上理解是"信號量"。

  那么什么是信號量呢?我用一種比較通俗的方式來跟大家解釋一下,就是在該類初始化的時候,給定一個數字A,每個線程調用acquire()方法后,首先判斷A是否大於0,如果大於0,就將A減去1,然后執行對應的線程,如果不大於0,那么就會阻塞,直到其他線程調用了release()方法,將A加上1,該線程可能有執行的機會。請各位讀者原諒筆者用這種粗俗的方式去解釋這個問題,而並非其他博文所用的專業性很強的"許可"之類的詞語,我認為專業的東西是給專業的人看的,很很多人想要去學習一個他根本就從未涉足的東西,那么我們就不能用專業的術語去描述,如果他能夠理解所謂的專業術語,那么他還有學習的必要嗎?

二. Semaphore的使用

  場景介紹:有一個停車場只有5個車位,現在有100輛車要去搶這個5個車位,理想情況下最多只有五輛車同時可以搶到車位,那么沒有搶到車位的車只能等到,其他的車讓出車位,才有機會去使用該車位。

public class CarPark {
    public static void main(String[] args) {
        //阻塞隊列
        BlockingQueue<String> parks = new LinkedBlockingQueue<>(5);

        parks.offer("車位一");
        parks.offer("車位二");
        parks.offer("車位三");
        parks.offer("車位四");
        parks.offer("車位五");

        ExecutorService executorService = Executors.newCachedThreadPool();

        //如博文中所說的初始值為5, 專業的說法就是5個許可證
        Semaphore semaphore = new Semaphore(5);

        for (int i = 0; i < 100; i++) {
            final int no = i;
            Thread t1 = new Thread(() -> {
                try {
                    /**
                     * 獲取許可,首先判斷semaphore內部的數字是否大於0,如果大於0,
                     * 才能獲得許可,然后將初始值5減去1,線程才會接着去執行;如果沒有
                     * 獲得許可(原因是因為已經有5個線程獲得到許可,semaphore內部的數字為0),
                     * 線程會阻塞直到已經獲得到許可的線程,調用release()方法,釋放掉許可,
                     * 也就是將semaphore內部的數字加1,該線程才有可能獲得許可。
                     */
                    semaphore.acquire();
                    /**
                     *  對應的線程會到阻塞對,對應車輛去獲取到車位,如果沒有拿到一致阻塞,
                     *  直到其他車輛歸還車位。
                     */
                    String park = parks.take();  
                    System.out.println("車輛【" + no + "】獲取到: " + park);
                    Thread.sleep((long) Math.random() * 6000);
                    semaphore.release(); //線程釋放掉許可,通俗來將就是將semaphore內部的數字加1
                    parks.offer(park);  //歸還車位
                    System.out.println("車輛【" + no + "】離開 " + park);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            executorService.execute(t1);
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM