Semaphore可翻译为信号量,它维护一组许可证, 每次尝试获取许可证时都将阻塞等待直到可获取,它才能获取到并解除阻塞状态。 Semaphore可以控制一些物理或逻辑资源的访问或使用,它常常用于限制线程数目。在实际开发中,可用作流量控制,特别对于一些公共资源有限的应用场景,如数据库连接,或是一些其他限流的缓存池。(基于JDK1.8)

2 示例

这是一个使用信号量控制对缓存池中items访问的示例。

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();
    }
}
SemaphoreDemo

相关文章:

  • 2022-03-01
猜你喜欢
  • 2022-01-22
  • 2021-07-16
  • 2021-04-02
  • 2021-11-13
  • 2022-02-21
  • 2021-08-09
  • 2021-05-24
相关资源
相似解决方案