美文网首页
并发工具类之Semaphore

并发工具类之Semaphore

作者: 逍遥白亦 | 来源:发表于2020-11-27 08:23 被阅读0次

    Semaphore(信号量)

    定义

    先看Java API中的定义

    A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it. Each release() adds a permit, potentially releasing a blocking acquirer. However, no actual permit objects are used; the Semaphore just keeps a count of the number available and acts accordingly.

    一个计数信号量。 在概念上,信号量维持一组许可证。 如果有必要,每个acquire()都会阻塞,直到许可证可用,然后才能使用它。 每个release()添加许可证,潜在地释放阻塞获取方。 但是,没有使用实际的许可证对象; Semaphore只保留可用数量的计数,并相应地执行。

    官方的例子

    信号量通常用于限制线程数,而不是访问某些(物理或逻辑)资源。 例如,这是一个使用信号量来控制对一个项目池的访问的类:

    class Pool {
       private static final int MAX_AVAILABLE = 100;
       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();
       }
    
       // Not a particularly efficient data structure; just for demo
    
       protected Object[] items = ... whatever kinds of items being managed
       protected boolean[] used = new boolean[MAX_AVAILABLE];
    
       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;
       }
     }
    

    具体引用

    在日常生活中,一些特别好吃的饭馆在饭点儿的时候,都需要等位,假设餐馆一共可以容纳30个顾客,而一共有100位顾客想要吃饭,如何有序的让所有顾客都能吃上饭呢?

    可以试着用信号量来试试。

    package SemaphoreTest;
    
    import java.util.Arrays;
    import java.util.Random;
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 顾客类
     */
    public class Customer implements Runnable {
    
        private int id;
    
        private Semaphore semaphore;
    
        private static Random random = new Random(30);
    
        public Customer(int id, Semaphore semaphore) {
            this.id = id;
            this.semaphore = semaphore;
        }
    
        public void run() {
            try {
                semaphore.acquire();
                System.out.println(this.id + "having dinner");
                TimeUnit.MILLISECONDS.sleep(random.nextInt(2000));
                semaphore.release();
                System.out.println(this.id + "is leaving");
            } catch (InterruptedException e){
                System.out.println(Arrays.toString(e.getStackTrace()));
            }
        }
    }
    
    
    package SemaphoreTest;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    
    public class Restaurant {
    
        private static int customerCount = 100;
    
        private static Semaphore semaphore = new Semaphore(30);
    
        private static ExecutorService threadPool = Executors.newFixedThreadPool(customerCount);
    
        public static void main(String[] args) {
    
            for (int i = 0; i < customerCount; i++){
                threadPool.execute(new Customer(i, semaphore));
            }
    
            threadPool.shutdown();
    
        }
    }
    
    

    相关文章

      网友评论

          本文标题:并发工具类之Semaphore

          本文链接:https://www.haomeiwen.com/subject/wjqtwktx.html