Semaphore是一個計數信號量,它的本質是一個"共享鎖"。
信號量維護了一個信號量許可集,Semaphore可以控同時訪問的線程個數,線程可以通過調用acquire()來獲取信號量的許可;當信號量中有可用的許可時,線程能獲取該許可;否則線程必須等待,直到有可用的許可爲止。 線程可以通過release()來釋放它所持有的信號量許可。
10個線程 搶佔5個信號量許可
package com.zewe.Semaphore;
import java.util.Random;
import java.util.concurrent.Semaphore;
/**
* 信號量
* 10個線程 搶佔5個信號量許可
* @author ZeWe
*
*/
public class SemaphoreTest {
private static int size = 5;
public static void main(String[] args) {
Semaphore sem = new Semaphore(size); // Semaphore(int permits, boolean fair) 創建具有給定的許可數和給定的公平設置的 Semaphore
for(int i=0; i<10; i++) {
new Thread(new Run(sem)).start();
}
}
}
class Run implements Runnable{
private Semaphore sem;
public Run(Semaphore sem) {
this.sem = sem;
}
@Override
public void run() {
try {
sem.acquire(); // 獲取一個許可,未獲取到之前線程阻塞; acquire(int permits) 獲取指定數目許可
System.out.println(Thread.currentThread().getName()+"獲取一個許可,準備執行。 剩餘許可數: "+sem.availablePermits());
Random sleep = new Random();
Thread.sleep((sleep.nextInt(5)+1)*1000);
sem.release(); // 釋放一個許可,將其返回給信號量; release(int permits) 釋放給定數目的許可,將其返回到信號量。
System.out.println(Thread.currentThread().getName()+"釋放一個許可,執行完畢。 剩餘許可數: "+sem.availablePermits());
} catch (Exception e) {
e.printStackTrace();
}
}
}
結果:
Thread-0獲取一個許可,準備執行。 剩餘許可數: 3
Thread-4獲取一個許可,準備執行。 剩餘許可數: 0
Thread-2獲取一個許可,準備執行。 剩餘許可數: 2
Thread-3獲取一個許可,準備執行。 剩餘許可數: 1
Thread-1獲取一個許可,準備執行。 剩餘許可數: 3
Thread-2釋放一個許可,執行完畢。 剩餘許可數: 2
Thread-5獲取一個許可,準備執行。 剩餘許可數: 1
Thread-0釋放一個許可,執行完畢。 剩餘許可數: 2
Thread-8獲取一個許可,準備執行。 剩餘許可數: 0
Thread-5釋放一個許可,執行完畢。 剩餘許可數: 1
Thread-7獲取一個許可,準備執行。 剩餘許可數: 0
Thread-3釋放一個許可,執行完畢。 剩餘許可數: 1
Thread-6獲取一個許可,準備執行。 剩餘許可數: 0
Thread-4釋放一個許可,執行完畢。 剩餘許可數: 3
Thread-1釋放一個許可,執行完畢。 剩餘許可數: 3
Thread-6釋放一個許可,執行完畢。 剩餘許可數: 3
Thread-9獲取一個許可,準備執行。 剩餘許可數: 2
Thread-8釋放一個許可,執行完畢。 剩餘許可數: 3
Thread-7釋放一個許可,執行完畢。 剩餘許可數: 4
Thread-9釋放一個許可,執行完畢。 剩餘許可數: 5