溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java并發(fā)編程中的Semaphore是什么意思

發(fā)布時間:2022-02-24 14:20:06 來源:億速云 閱讀:112 作者:小新 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)Java并發(fā)編程中的Semaphore是什么意思,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

    簡介

    Semaphore是用來限制訪問特定資源的并發(fā)線程的數(shù)量,相對于內(nèi)置鎖synchronized和重入鎖ReentrantLock的互斥性來說,Semaphore可以允許多個線程同時訪問共享資源。

    Semaphored的使用

    構(gòu)造方法

    Semaphore(int permits):創(chuàng)建Semaphore,并指定許可證的數(shù)量。(公平策略為非公平)

    Semaphore(int permits, boolean fair):創(chuàng)建Semaphore,并指定許可證的數(shù)量和公平策略。

    核心方法

    acquire():從Semaphore中獲取一個許可證,如果獲取不到則阻塞等待,直到其他線程釋放了一個許可證或者當(dāng)前線程被中斷。

    acquire(int permits):從Semaphore中獲取指定數(shù)量的許可證,如果獲取不到則阻塞等待,直到其他線程釋放了對應(yīng)數(shù)量的許可證或者當(dāng)前線程被中斷。

    acquireUninterruptibly():從Semaphore中獲取一個許可證,如果獲取不到則阻塞等待,直到其他線程釋放了一個許可證。(不響應(yīng)中斷)

    tryAcquire():嘗試從Semaphore中獲取一個許可證,獲取成功則返回true,獲取失敗則返回false,不會進(jìn)行等待。(不受公平策略的影響,許可證可用則立即獲得)

    tryAcquire(long timeout, TimeUnit unit):嘗試從Semaphore中獲取一個許可證,獲取成功則返回true,獲取失敗則等待指定的時間,直到等待時間結(jié)束還是沒有獲取到許可證則返回false。

    release():釋放一個許可證。

    release(int permits):釋放指定數(shù)量的許可證。

    示例

    總共有5個許可證,最先獲取到許可證的5個線程開始執(zhí)行任務(wù),沒獲取到的線程進(jìn)入等待狀態(tài),直到獲取到許可證的線程釋放許可證后,再獲取許可證執(zhí)行任務(wù)。

    public class Demo {
    
        public static void main(String[] args) {
            //創(chuàng)建許可證數(shù)量為5的Semaphore
            Semaphore semaphore = new Semaphore(5);
    
            Runnable runnable = () -> {
                String threadName = Thread.currentThread().getName();
                try{
                    //獲取一個許可證
                    semaphore.acquire();
                    System.out.println(threadName + "執(zhí)行任務(wù)...");
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //釋放一個許可證
                    semaphore.release();
                }
            };
    
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for(int i = 0; i < 10; i++){
                executorService.execute(runnable);
            }
    
            executorService.shutdown();
        }
    
    }
    
    /* 開始輸出:
     * pool-1-thread-1執(zhí)行任務(wù)...
     * pool-1-thread-5執(zhí)行任務(wù)...
     * pool-1-thread-6執(zhí)行任務(wù)...
     * pool-1-thread-7執(zhí)行任務(wù)...
     * pool-1-thread-3執(zhí)行任務(wù)...
     * 三秒后輸出:
     * pool-1-thread-4執(zhí)行任務(wù)...
     * pool-1-thread-8執(zhí)行任務(wù)...
     * pool-1-thread-2執(zhí)行任務(wù)...
     * pool-1-thread-10執(zhí)行任務(wù)...
     * pool-1-thread-9執(zhí)行任務(wù)...
     */

    使用Semaphore實現(xiàn)互斥

    使用Semaphore實現(xiàn)互斥只需要將許可證數(shù)量設(shè)置為1,這樣就可以保證只有一個線程能獲取到許可證。

    Semaphore semaphore = new Semaphore(1);

    相比內(nèi)置鎖synchronized和重入鎖ReentrantLock,使用Semaphore實現(xiàn)互斥有個明顯的缺點:不可重入,沒有釋放許可證的情況下,再次調(diào)acquire方法將導(dǎo)致死鎖。

    示例:

    public class Demo {
    
        public static void main(String[] args) {
            Semaphore semaphore = new Semaphore(1);
    
            Runnable runnable = () -> {
                String threadName = Thread.currentThread().getName();
                try {
                    //獲取一個許可證
                    semaphore.acquire();
                    System.out.println(threadName + "執(zhí)行任務(wù)A...");
                    semaphore.acquire();
                    System.out.println(threadName + "執(zhí)行任務(wù)B...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //釋放一個許可證
                    semaphore.release();
                }
            };
    
            new Thread(runnable).start();
        }
    
    }
    
    /*
     * 輸出結(jié)果:
     * Thread-0執(zhí)行任務(wù)A...
     */

    “執(zhí)行任務(wù)B”永遠(yuǎn)不會打印,因為許可證只有一個,第二次acquire方法的調(diào)用會因為無法獲取到許可證而一直阻塞。

    關(guān)于“Java并發(fā)編程中的Semaphore是什么意思”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI