zoukankan      html  css  js  c++  java
  • Semaphore的简介及应用场景

    Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目。

    常用函数: 
    信号量的构造函数 
    非公平:

    public Semaphore(int permits);//permits就是允许同时运行的线程数目

    公平(获得锁的顺序与线程启动顺序有关):

    public Semaphore(int permits,boolean fair);//permits就是允许同时运行的线程数目

    创建一个信号量

    Semaphore semaphore = new Semaphore(2);

    从信号量中获取一个许可

    semaphore.acquire();

    释放一个许可(在释放许可之前,必须先获获得许可。)

    semaphore.release();

    尝试获取一个许可,若获取成功返回true,若获取失败返回false

    semaphore.tryAcquire();

    所有函数:

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

    代码实例: 
    假设有10个人在银行办理业务,只有2个工作窗口,代码实现逻辑如下

    public class SemaphoreDemo {
    
        // 排队总人数(请求总数)
        public static int clientTotal = 10;
    
        // 可同时受理业务的窗口数量(同时并发执行的线程数)
        public static int threadTotal = 2;
    
    
        public static void main(String[] args) throws Exception {
            ExecutorService executorService = Executors.newCachedThreadPool();
            final Semaphore semaphore = new Semaphore(threadTotal);
            final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
            for (int i = 0; i < clientTotal; i++) {
                final int count = i;
                executorService.execute(() -> {
                    try {
                        semaphore.acquire(1);
                        resolve(count);
                        semaphore.release(2);
                    } catch (Exception e) {
                        log.error("exception", e);
                    }
                    countDownLatch.countDown();
                });
            }
            countDownLatch.await();
            executorService.shutdown();
        }
    
        private static void resolve(int i) throws InterruptedException {
            log.info("服务号{},受理业务中。。。", i);
            Thread.sleep(2000);
        }
    }

    输出结果:

    21:39:10.038 [pool-1-thread-1] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号0,受理业务中。。。
    21:39:10.038 [pool-1-thread-2] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号1,受理业务中。。。
    21:39:12.043 [pool-1-thread-4] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号3,受理业务中。。。
    21:39:12.043 [pool-1-thread-3] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号2,受理业务中。。。
    21:39:14.044 [pool-1-thread-6] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号5,受理业务中。。。
    21:39:14.044 [pool-1-thread-5] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号4,受理业务中。。。
    21:39:16.045 [pool-1-thread-7] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号6,受理业务中。。。
    21:39:16.045 [pool-1-thread-8] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号7,受理业务中。。。
    21:39:18.045 [pool-1-thread-10] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号9,受理业务中。。。
    21:39:18.045 [pool-1-thread-9] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号8,受理业务中。。。

    从输出结果可以看出,每隔两秒,有两个线程被执行

    原文链接:https://blog.csdn.net/yuruixin_china/article/details/82084946

    Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目。
    常用函数: 信号量的构造函数 非公平:
    public Semaphore(int permits);//permits就是允许同时运行的线程数目1公平(获得锁的顺序与线程启动顺序有关):
    public Semaphore(int permits,boolean fair);//permits就是允许同时运行的线程数目1创建一个信号量
    Semaphore semaphore = new Semaphore(2);1从信号量中获取一个许可
    semaphore.acquire();1释放一个许可(在释放许可之前,必须先获获得许可。)
    semaphore.release();1尝试获取一个许可,若获取成功返回true,若获取失败返回false
    semaphore.tryAcquire();1所有函数:
    // 创建具有给定的许可数和非公平的公平设置的 Semaphore。Semaphore(int permits)// 创建具有给定的许可数和给定的公平设置的 Semaphore。Semaphore(int permits, boolean fair)
    // 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。void acquire()// 从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。void acquire(int permits)// 从此信号量中获取许可,在有可用的许可前将其阻塞。void acquireUninterruptibly()// 从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞。void acquireUninterruptibly(int permits)// 返回此信号量中当前可用的许可数。int availablePermits()// 获取并返回立即可用的所有许可。int drainPermits()// 返回一个 collection,包含可能等待获取的线程。protected Collection<Thread> getQueuedThreads()// 返回正在等待获取的线程的估计数目。int getQueueLength()// 查询是否有线程正在等待获取。boolean hasQueuedThreads()// 如果此信号量的公平设置为 true,则返回 true。boolean isFair()// 根据指定的缩减量减小可用许可的数目。protected void reducePermits(int reduction)// 释放一个许可,将其返回给信号量。void release()// 释放给定数目的许可,将其返回到信号量。void release(int permits)// 返回标识此信号量的字符串,以及信号量的状态。String toString()// 仅在调用时此信号量存在一个可用许可,才从信号量获取许可。boolean tryAcquire()// 仅在调用时此信号量中有给定数目的许可时,才从此信号量中获取这些许可。boolean tryAcquire(int permits)// 如果在给定的等待时间内此信号量有可用的所有许可,并且当前线程未被中断,则从此信号量获取给定数目的许可。boolean tryAcquire(int permits, long timeout, TimeUnit unit)// 如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。boolean tryAcquire(long timeout, TimeUnit unit)1234567891011121314151617181920212223242526272829303132333435363738394041代码实例: 假设有10个人在银行办理业务,只有2个工作窗口,代码实现逻辑如下
    package com..concurrency.yuxin.demo;
    import lombok.extern.slf4j.Slf4j;import org.joda.time.DateTime;import org.joda.time.format.DateTimeFormat;import org.joda.time.format.DateTimeFormatter;
    import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;
    @Slf4jpublic class SemaphoreDemo {
        // 排队总人数(请求总数)    public static int clientTotal = 10;
        // 可同时受理业务的窗口数量(同时并发执行的线程数)    public static int threadTotal = 2;

        public static void main(String[] args) throws Exception {        ExecutorService executorService = Executors.newCachedThreadPool();        final Semaphore semaphore = new Semaphore(threadTotal);        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);        for (int i = 0; i < clientTotal; i++) {            final int count = i;            executorService.execute(() -> {                try {                    semaphore.acquire(1);                    resolve(count);                    semaphore.release(2);                } catch (Exception e) {                    log.error("exception", e);                }                countDownLatch.countDown();            });        }        countDownLatch.await();        executorService.shutdown();    }
        private static void resolve(int i) throws InterruptedException {        log.info("服务号{},受理业务中。。。", i);        Thread.sleep(2000);    }}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849输出结果:
    21:39:10.038 [pool-1-thread-1] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号0,受理业务中。。。21:39:10.038 [pool-1-thread-2] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号1,受理业务中。。。21:39:12.043 [pool-1-thread-4] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号3,受理业务中。。。21:39:12.043 [pool-1-thread-3] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号2,受理业务中。。。21:39:14.044 [pool-1-thread-6] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号5,受理业务中。。。21:39:14.044 [pool-1-thread-5] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号4,受理业务中。。。21:39:16.045 [pool-1-thread-7] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号6,受理业务中。。。21:39:16.045 [pool-1-thread-8] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号7,受理业务中。。。21:39:18.045 [pool-1-thread-10] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号9,受理业务中。。。21:39:18.045 [pool-1-thread-9] INFO com.concurrency.yuxin.demo.SemaphoreDemo - 服务号8,受理业务中。。。12345678910从输出结果可以看出,每隔两秒,有两个线程被执行--------------------- 版权声明:本文为CSDN博主「yuruixin_china」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/yuruixin_china/article/details/82084946

  • 相关阅读:
    类变量、绑定方法、静态方法和类方法
    面向对象练习及补充
    2、error:file /usr/bin/ ** mysql-client-5.6.39-1.el7.x86_64
    15、Linux 磁盘映射DM
    14、echo “$JAVA_HOME/bin” >>/etc/profile 转义
    typora文件导出word
    1、Rocketmq centos7下安装及使用
    13、hostname及hostnamectl区别
    1、MySql集群
    Hadoop安装
  • 原文地址:https://www.cnblogs.com/JavaHxm/p/11341186.html
Copyright © 2011-2022 走看看