• Semaphore信号量


    1、Semaphore介绍

      Semaphore 通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。

    2、Semaphore常用方法

    acquire()  
    获取一个令牌,在获取到令牌、或者被其他线程调用中断之前线程一直处于阻塞状态。
    ​
    acquire(int permits)  
    获取一个令牌,在获取到令牌、或者被其他线程调用中断、或超时之前线程一直处于阻塞状态。
        
    acquireUninterruptibly() 
    获取一个令牌,在获取到令牌之前线程一直处于阻塞状态(忽略中断)。
        
    tryAcquire()
    尝试获得令牌,返回获取令牌成功或失败,不阻塞线程。
    ​
    tryAcquire(long timeout, TimeUnit unit)
    尝试获得令牌,在超时时间内循环尝试获取,直到尝试获取成功或超时返回,不阻塞线程。
    ​
    release()
    释放一个令牌,唤醒一个获取令牌不成功的阻塞线程。
    ​
    hasQueuedThreads()
    等待队列里是否还存在等待线程。
    ​
    getQueueLength()
    获取等待队列里阻塞的线程数。
    ​
    drainPermits()
    清空令牌把可用令牌数置为0,返回清空令牌的数量。
    ​
    availablePermits()
    返回可用的令牌数量。

    3、使用场景,LeetCode多线程题

    我们提供一个类:
    
    class FooBar {
      public void foo() {
        for (int i = 0; i < n; i++) {
          print("foo");
        }
      }
    
      public void bar() {
        for (int i = 0; i < n; i++) {
          print("bar");
        }
      }
    }
    两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。
    
    请设计修改程序,以确保 "foobar" 被输出 n 次。
    
     

    解决代码:

    class FooBar {
        private int n;
    
        public FooBar(int n) {
            this.n = n;
        }
        // 创建执行foo和bar的信号量
        Semaphore fooSemaphore = new Semaphore(1); // 默认可执行
        Semaphore barSemaphore = new Semaphore(0);
        public void foo(Runnable printFoo) throws InterruptedException {
    
            for (int i = 0; i < n; i++) {
                fooSemaphore.acquire();
                // printFoo.run() outputs "foo". Do not change or remove this line.
                printFoo.run();
                barSemaphore.release();
            }
        }
    
        public void bar(Runnable printBar) throws InterruptedException {
    
            for (int i = 0; i < n; i++) {
                barSemaphore.acquire();
                // printBar.run() outputs "bar". Do not change or remove this line.
                printBar.run();
                fooSemaphore.release();
            }
        }
    }
  • 相关阅读:
    HDU 1754 I Hate It (线段树)
    HDU 1394 Minimum Inversion Number (树状数组)
    天梯赛 L2-012 关于堆的判断 (二叉树)
    HDU 1166 敌兵布阵 (树状数组 单点修改+区间查询)
    [leetcode-77-Combinations]
    [leetcode-101-Symmetric Tree]
    [leetcode-21-Merge Two Sorted Lists]
    [leetcode-109-Convert Sorted List to Binary Search Tree]
    [leetcode-507-Perfect Number]
    [leetcode-537-Complex Number Multiplication]
  • 原文地址:https://www.cnblogs.com/brucebai/p/13628073.html
Copyright © 2020-2023  润新知