Semaphore(信号灯)

Semaphore(信号灯)

文档解释:
    一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。

    此类的构造方法可选地接受一个公平 参数。当设置为 false 时,此类不对线程获取许可的顺序做任何保证。特别地,闯入 是允许的,也就是说可以在已经等待的线程前为调用 acquire() 的线程分配一个许可,从逻辑上说,就是新线程将自己置于等待线程队列的头部。当公平设置为 true 时,信号量保证对于任何调用获取方法的线程而言,都按照处理它们调用这些方法的顺序(即先进先出;FIFO)来选择线程、获得许可。注意,FIFO 排序必然应用到这些方法内的指定内部执行点。所以,可能某个线程先于另一个线程调用了 acquire,但是却在该线程之后到达排序点,并且从方法返回时也类似。还要注意,非同步的 tryAcquire 方法不使用公平设置,而是使用任意可用的许可。

    通常,应该将用于控制资源访问的信号量初始化为公平的,以确保所有线程都可访问资源。为其他的种类的同步控制使用信号量时,非公平排序的吞吐量优势通常要比公平考虑更为重要。

构造方法摘要

  1. Semaphore(int permits)
    创建具有给定的许可数和非公平的公平设置的 Semaphore。
  2. Semaphore(int permits, boolean fair)
    创建具有给定的许可数和给定的公平设置的 Semaphore。

方法摘要:

  1. void acquire()
    从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
  2. void acquire(int permits)
    从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。
  3. void acquireUninterruptibly()
    从此信号量中获取许可,在有可用的许可前将其阻塞。
  4. void acquireUninterruptibly(int permits)
    从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞。
  5. int availablePermits()
    返回此信号量中当前可用的许可数。
  6. int drainPermits()
    获取并返回立即可用的所有许可。
    7 .protected Collection getQueuedThreads()
    返回一个 collection,包含可能等待获取的线程。
  7. int getQueueLength()
    返回正在等待获取的线程的估计数目。
  8. boolean hasQueuedThreads()
    查询是否有线程正在等待获取。
  9. boolean isFair()
    如果此信号量的公平设置为 true,则返回 true。
  10. protected void reducePermits(int reduction)
    根据指定的缩减量减小可用许可的数目。
  11. void release()
    释放一个许可,将其返回给信号量。
  12. void release(int permits)
    释放给定数目的许可,将其返回到信号量。
  13. String toString()
    返回标识此信号量的字符串,以及信号量的状态。
  14. boolean tryAcquire()
    仅在调用时此信号量存在一个可用许可,才从信号量获取许可。
  15. boolean tryAcquire(int permits)
    仅在调用时此信号量中有给定数目的许可时,才从此信号量中获取这些许可。
  16. boolean tryAcquire(int permits, long timeout, TimeUnit unit)
    如果在给定的等待时间内此信号量有可用的所有许可,并且当前线程未被中断,则从此信号量获取给定数目的许可。
  17. boolean tryAcquire(long timeout, TimeUnit unit)
    如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * Semaphore: 信号灯
 *   解释:一个计数信号量。从概念上讲,信号量维护了一个许可集。
 *      如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。
 *      每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。
 *      但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。
 *  简明解释:
 *      Semaphore对象中,存在一个信号值,比如存在Samephore中存在三个信号值,
 *      存在6个线程,那么只有三个线程通过acquire()方法,有机会,暂时拥有Samephore一段时间
 *      ,一旦调用release()方法之后,那么拥有Semaphore的线程,将会失去机会
 *      ,被下一个拿到acquire()方法的线程,拥有Semaphore,直到调用release()方法,重复该过程
 */
public class SemaphoreUse {
    public static void main(String[] args) {
        Semaphore semaphore=new Semaphore(3);
        for (int i = 1; i <=6 ; i++) {
            new Thread(() -> {
                try {
                    //线程拥有Semaphore对象的资格
                    semaphore.acquire();
                    //设置当前线程睡眠时间
                    TimeUnit.SECONDS.sleep(new Random().nextInt(2));
                    System.out.println(Thread.currentThread().getName() + "...拥有..Semaphore");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放当前线程拥有Semaphore对象的资格
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName() + "...释放 ------- Semaphore");
                }
            }, "线程:" + String.valueOf(i)).start();

        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值