Semaphore可翻译为信号量,它维护一组许可证, 每次尝试获取许可证时都将阻塞等待直到可获取,它才能获取到并解除阻塞状态。 Semaphore可以控制一些物理或逻辑资源的访问或使用,它常常用于限制线程数目。在实际开发中,可用作流量控制,特别对于一些公共资源有限的应用场景,如数据库连接,或是一些其他限流的缓存池。(基于JDK1.8)
2 示例
public class SemaphoreDemo { static class Pool { private static final int MAX_AVAILABLE = 6; private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); public Object getItem() throws InterruptedException { available.acquire(); return getNextAvailableItem(); } public void putItem(Object x) { if (markAsUnused(x)) available.release(); } protected Object[] items; protected boolean[] used = new boolean[MAX_AVAILABLE]; Pool() { items = new Object[15]; for (int i = 0; i < items.length; i++) { items[i] = "item" + i; } } protected synchronized Object getNextAvailableItem() { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (!used[i]) { used[i] = true; return items[i]; } } return null; // not reached } protected synchronized boolean markAsUnused(Object item) { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (item == items[i]) { if (used[i]) { used[i] = false; return true; } else return false; } } return false; } } public static void main(String[] args) { final int THREAD_COUNT = 10; ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT); Pool pool = new Pool(); for (int i = 0; i < THREAD_COUNT; i++) { int tmpI = i; threadPool.submit(() -> { try { Object item = pool.getItem(); System.out.printf("当前线程:%s,获取到缓存池中的资源:%s\n", Thread.currentThread().getName(), item); Thread.sleep(7); pool.putItem(item); System.out.printf("当前线程:%s,已将缓存池中的资源%s放回池中\n", Thread.currentThread().getName(), item); } catch (InterruptedException e) { e.printStackTrace(); } }); } threadPool.shutdown(); } }