Semaphore:信号量通常用于限制线程的数量访问一些(物理或逻辑)资源。个人理解:限流、控制访问量。
使用场景:竞争仅有的资源、一个车厢最多可容纳多少人数,超载则不能上车,或者每条通道一次仅能n个人进入,剩下的需要排队等等。。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Semaphore;
/**
* 信号量
* Semaphore限流、控制访问量
*/
public class SemaphoreTest {
public static final Logger logger = LoggerFactory.getLogger(SemaphoreTest.class);
public static void main(String[] args) {
/**
* Creates a {@code Semaphore} with the given number of
* permits and nonfair fairness setting.
*
* @param permits the initial number of permits available.
* This value may be negative, in which case releases
* must occur before any acquires will be granted.
*/
// public Semaphore(int permits);
/**
* Creates a {@code Semaphore} with the given number of
* permits and the given fairness setting.
*
* @param permits the initial number of permits available.
* This value may be negative, in which case releases
* must occur before any acquires will be granted.
* @param fair {@code true} if this semaphore will guarantee
* first-in first-out granting of permits under contention,
* else {@code false}
*/
// public Semaphore(int permits, boolean fair);
//初始化2个信号量,也就是说同时最多只能有2个请求的访问
Semaphore semaphore = new Semaphore(2);
//模拟5次调用,循环5次,开启5个异步线程
for (int i = 1; i <= 5; i++) {
new Thread(() -> {
try {
//获得访问机会
semaphore.acquire();
logger.info(Thread.currentThread().getName() + "获得访问机会!");
} catch (InterruptedException e) {
e.printStackTrace();
}
//假设这里有一个1秒钟的任务,阻塞一秒
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
//释放许可,
logger.info(Thread.currentThread().getName() + "释放许可,释放当前线程!");
semaphore.release();
logger.info(Thread.currentThread().getName() + "================================================");
}).start();
}
}
}
Semaphore并不能保证程序的顺序和安全性。
输出日志:
11:59:54.157 [Thread-1] INFO com.test.tenant.SemaphoreTest - Thread-1获得访问机会!
11:59:54.157 [Thread-0] INFO com.test.tenant.SemaphoreTest - Thread-0获得访问机会!
11:59:55.165 [Thread-0] INFO com.test.tenant.SemaphoreTest - Thread-0释放许可,释放当前线程!
11:59:55.165 [Thread-1] INFO com.test.tenant.SemaphoreTest - Thread-1释放许可,释放当前线程!
11:59:55.165 [Thread-0] INFO com.test.tenant.SemaphoreTest - Thread-0================================================
11:59:55.165 [Thread-1] INFO com.test.tenant.SemaphoreTest - Thread-1================================================
11:59:55.165 [Thread-2] INFO com.test.tenant.SemaphoreTest - Thread-2获得访问机会!
11:59:55.165 [Thread-3] INFO com.test.tenant.SemaphoreTest - Thread-3获得访问机会!
11:59:56.167 [Thread-3] INFO com.test.tenant.SemaphoreTest - Thread-3释放许可,释放当前线程!
11:59:56.167 [Thread-2] INFO com.test.tenant.SemaphoreTest - Thread-2释放许可,释放当前线程!
11:59:56.168 [Thread-3] INFO com.test.tenant.SemaphoreTest - Thread-3================================================
11:59:56.168 [Thread-2] INFO com.test.tenant.SemaphoreTest - Thread-2================================================
11:59:56.168 [Thread-4] INFO com.test.tenant.SemaphoreTest - Thread-4获得访问机会!
11:59:57.172 [Thread-4] INFO com.test.tenant.SemaphoreTest - Thread-4释放许可,释放当前线程!
11:59:57.173 [Thread-4] INFO com.test.tenant.SemaphoreTest - Thread-4================================================