• 信号量Semaphore


    Semaphore也就是信号量,提供了资源数量的并发访问控制

    有两个构造方法:

    public Semaphore(int permits)
    public Semaphore(int permits, boolean fair)
    

    fire表示公平,permits表示许可数量。

    Semaphore的方法与锁是类似的,主要的方法有两类,获取许可和释放许可,主要方法有:

    //阻塞获取许可
    public void acquire() throws InterruptedException
    //阻塞获取许可,不响应中断
    public void acquireUninterruptibly()
    //批量获取多个许可
    public void acquire(int permits) throws InterruptedException
    public void acquireUninterruptibly(int permits)
    //尝试获取
    public boolean tryAcquire()
    //限定等待时间获取
    public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException
    //释放许可
    public void release()
    

    需要说明的是,如果我们将permits的值设为1,你可能会认为它就变成了一般的锁,不过,它与一般的锁是不同的。一般锁只能由持有锁的线程释放,而Semaphore表示的只是一个许可数,任意线程都可以调用其release方法。主要的锁实现类ReentrantLock是可重入的,而Semaphore不是,每一次的acquire调用都会消耗一个许可,比如,看下面的代码段:

    Semaphore permits = new Semaphore(1);
    permits.acquire();
    permits.acquire();
    System.out.println("acquired");
    

    程序会阻塞在第二个acquire调用,永远都不会输出“acquired”。

    信号量的基本原理比较简单,也是基于AQS实现的,permits表示共享的锁个数, acquire方法就是检查锁个数是否大于0,大于则减一,获取成功,否则就等待,release就是将锁个数加一,唤醒第一个等待的线程。

    获取释放许可的代码示例:

    public class SemaphoreTest {
        private static final int THREAD_COUNT = 30;
        private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
        private static Semaphore s = new Semaphore(10);
        public static void main(String[] args) {
            for (int i = 0; i < THREAD_COUNT; i++) {
                threadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            s.acquire();
                            System.out.println("save data");
                            s.release();
                        } catch (InterruptedException e) {
                        }
                    }
                });
            }
            threadPool.shutdown();
        }
    }
    

    参考: Java编程的逻辑 19.2 信号量Semaphore

  • 相关阅读:
    一:字符串中匹配中文
    flask+gevent的异步框架
    linux常见的操作指令
    Markdown语法
    Git常用操作
    Vim
    IDEA使用汇总
    Maven基本使用汇总
    Zookeeper问题汇总
    编程最佳实践
  • 原文地址:https://www.cnblogs.com/ooo0/p/15845408.html
Copyright © 2020-2023  润新知