並發控制-信號量(Semaphore)


信號量用來控制有限資源的方法,舉例:假如信號量為3,則同時只有3個線程共享。

概述

  信號量用來控制系統耗時資源的訪問,一般我們初始設置了一個公平的信號量,線程在使用時需要申請,用完之后需要釋放。

使用流程

  信號量Semaphore的使用流程如下:

  一般設置公平的信號量-->線程在使用時需要進行require申請-->若可以申請到,則執行自己的邏輯-->執行完成后,需要釋放信號量

  -->若未申請到,則可以阻塞,直到申請到。

主要方法

  信號量的部分常用方法如下:

  1.信號量構造:public Semaphore(int permits, boolean fair) 

  2.獲取信號量:public void acquire();acquireUninterruptibly();tryAcquire() ;tryAcquire(long timeout, TimeUnit unit)

  3.釋放信號量:release();release(int permits)

實例代碼

  下面我們通過初始化一個3容量的信號量,我們用100個線程去獲取這個信號量,每次申請一個信號量,當用完之后,我們釋放這一個,如以下實例代碼所示:

  

package com.yang.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.stream.IntStream;

public class SemaphoreDemp {
    static Semaphore   semaphore  =new Semaphore(3,true);

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 100; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName()+"等待獲取信號量");
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName()+"取到了信號量");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        System.out.println(Thread.currentThread().getName()+"釋放信號量");
                        semaphore.release();
                    }
                }
            };
            executorService.submit(runnable);
        }
        executorService.shutdown();
    }
}

  運行結果如下圖所示:

  

 

 

特殊用法及注意點

  1.申請和釋放的信號量必須保持一致,在信號量申請時,比如我們可以申請2個,釋放的時候也可以釋放2個,這個場景是指程序在運行時,可能需要多個資源

  2.信號量在初始化的時候,可以設置為公平或者非公平,我們一般設置為公平,對耗時長的資源訪問時,一般不允許爭奪

  3.信號量在獲取和釋放時,對是否是同一個線程沒有限制。

 


免責聲明!

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



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