信號量Semaphore的使用

允許多個線程同時訪問:信號量(Semaphore)

信號量爲多線程協作提供了更爲強大的控制方法。廣義上說,信號量是對鎖的擴展。無論是內部鎖synchronized還是重入鎖ReentrantLock,一次都只允許一個線程訪問一個資源,而信號量指定多個線程訪問同一個資源。
信號主要提供以下的構造函數。

public Semaphore(int permits);//permits 指定信號量的准入數
public Semaphore(int permits,boolean fair);//第二個參數指定是否公平

在構造信號量時,必須指定信號量的准入數,即同時能申請多少許可,若一個線程每次只申請一個許可,這就相當於指定了同時允許多少個線程能訪問同一資源。
信號量的主要邏輯方法包括以下幾種:

public void acquire();
public void acquireUninterruptibly();
public boolean tryAcquire();
public boolean tryAcquire(long timeout,TimeUnit unit);
public void release();

acquire()方法嘗試獲得一個准入的許可。若無法獲得,線程會等待,直到有線程釋放一個許可或者線程被中斷。acquireUninterruptibly()方法和acquire()方法類似,但是不能相應中斷。tryacquire()嘗試獲得一個許可,成功返回true失敗返回false,他不會進行等待,立即返回。release()用於在線程訪問資源結束後,釋放一個許可,使其他線程可以進行資源訪問。
下面我們使用一個例子來演示信號量的使用:

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

public class SemapDemo implements Runnable {

    final Semaphore semp=new Semaphore(5);

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            semp.acquire();
            Thread.sleep(2000);
            System.out.println(Thread.currentThread().getId()+":done!");
            semp.release();
        }catch(InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ExecutorService exec=Executors.newFixedThreadPool(20);
        final SemapDemo demo=new SemapDemo();
        for(int i=0;i<20;i++) {
            exec.submit(demo);
        }
    }

}

可以看到程序會限制執行這段代碼的線程數,觀察結果可以看到每次5個線程一組,因爲我們設置了允許5個許可的信號量。

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