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