semphore详解

3 篇文章 0 订阅
1 篇文章 0 订阅
Semaphore作为信号量,用于控制同时访问特定资源的线程数量。本文详细介绍了其构造函数、核心方法,并通过顺序打印ABC十遍的应用场景进行实战演示。
摘要由CSDN通过智能技术生成

semphore作用

  • Semaphore 字面意思是信号量的意思,它的作用是控制访问特定资源的线程数目

semphore构造函数

  /**
     * permits:许可线程的数量,代表同一时间,最多允许permits个线程执行acquire() 和release() 之间      * 的代码。同时内部变量state许可量的值等于permits
     */
    public Semaphore(int permits) {
        //默认非公平锁
        sync = new NonfairSync(permits);
    }

    /**
     * fair:表示公平性
     * False:表示非公平信号量,即线程启动的顺序与调用semaphore.acquire() 的顺序无关,也就是线程先      * 启动了并不代表先获得 许可。
     * True:公平信号量,即线程启动的顺序与调用semaphore.acquire() 的顺序有关,也就是先启动的线程      * 优先获得许可
     */
    public Semaphore(int permits, boolean fair) {
        //根据fair值判断公平锁或非公平锁
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

semphore核心方法

   /**
     * 获取1个许可,当获取不到时线程阻塞直到获取到许可
     */
    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    /**
     *释放一个许可
     */
    public void release() {
        sync.releaseShared(1);
    }
   /**
     * 获取permits个许可,当获取不到时线程阻塞直到获取到许可
     */
    public void acquire(int permits) throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireSharedInterruptibly(permits);
    }
   /**
     * 释放permits个许可
     */
    public void release(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        sync.releaseShared(permits);
    }
    /**
     * 使等待进入acquireUninterruptibly()方法的线程,不允许被中断。理解:线程调用acquire()方法时      * 如果获取不到许可则会阻塞,此时调用interrupt方法则会抛出中断异常,使用      acquireUninterruptibly则等待线程不能被中断
     */
    public void acquireUninterruptibly() {
        sync.acquireShared(1);
    }
   /**
     * 在等待许可的情况下不允许中断,如果成功获得锁,则取得指定的permits许可个数
     */
    public void acquireUninterruptibly(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireShared(permits);
    }

    /**
     * 尝试获取1个许可。如果获取不到则返回false,通常与if语句结合使用,其具有无阻塞的特点
     */
    public boolean tryAcquire() {
        return sync.nonfairTryAcquireShared(1) >= 0;
    }

    /**
     * 在指定的时间内尝试获取1个许可,如果获取不到则返回false
     */
    public boolean tryAcquire(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }
    /**
     * 尝试获取permits个许可,如果获取不到则返回false
     */
    public boolean tryAcquire(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        return sync.nonfairTryAcquireShared(permits) >= 0;
    }

    /**
     * 在指定的时间内尝试获取permits个许可,如果获取不到则返回false
     */
    public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
        throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
    }

    /**
     *Semaphore对象中当前可以用的许可数
     */
    public int availablePermits() {
        return sync.getPermits();
    }

    /**
     * 获取并返回所有的许可个数,并且将可用的许可重置为0
     */
    public int drainPermits() {
        return sync.drainPermits();
    }
  /**
     * 判断有没有线程在等待这个许可
     */
    public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    /**
     * 取得等待许可的线程个数
     */
    public final int getQueueLength() {
        return sync.getQueueLength();
    }

应用场景:使用semphore顺序打印ABC十遍

public class Work implements Runnable {
    private String key;
    private Semaphore current;
    private Semaphore next;
    private Integer count;

    public Work( Semaphore current, Semaphore next, String key,Integer count) {
        this.key = key;
        this.current = current;
        this.next = next;
        this.count = count;
    }

    @Override
    public void run() {
        for (int i = 0; i < count; i++) {
            try {
                //获取一个许可
                current.acquire();
                System.out.println(i+","+key);
                //增加next的一个许可,这样next就可以获取到许可执行下面的代码逻辑
                next.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Semaphore a = new Semaphore(1);
        Semaphore b = new Semaphore(0);
        Semaphore c = new Semaphore(0);
        ExecutorService poolService = Executors.newFixedThreadPool(3);
        Integer count=10;
        poolService.execute(new Work(a,b,"A",count));
        poolService.execute(new Work(b,c,"B",count));
        poolService.execute(new Work(c,a,"C",count));
        try {
            Thread.sleep(3000);
            poolService.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值