• Java中的信号量Semaphore


    信号量的实现模型一般包括:1个计数器、1个等待队列、3个方法(需要保证原子性)

    Semaphore 实现的伪代码(JDK 中 Semaphore 是基于 AbstractQueuedSynchronizer 实现,可以指定是否公平):

    class Semaphore{
        //计数器
        int count;
        
        //等待队列
        Queue queue;
        
        //初始化
        Semaphore(int c){
            this.count=c;
        }
        
        //获取许可证
        void acquire(){
            count--;
            if(count<0){
                //将当前线程插入等待队列
                //阻塞当前线程
            }
        }
        
        //获取许可证
        void release(){
            count++;
            if(count<=0) {
                //移除等待队列中的某个线程
                //唤醒某个线程
            }
        }
    }

    使用信号量实现互斥锁效果:

    package constxiong.interview;
    
    import java.util.concurrent.Semaphore;
    
    /**
     * 测试使用信号量实现锁的效果
     * @author ConstXiong
     * @date 2019-12-18 14:18:47
     */
    public class TestSemaphore {
    
        private static int count;
        
        private static Semaphore semaphore = new Semaphore(1); 
        
        public static void main(String[] args) {
            for (int i = 0; i < 100; i++) {
                new Thread(() -> {
                    add();
                    System.out.println(count);
                }).start();
            }
        }
        
        private static void add() {
            try {
                semaphore.acquire();
                Thread.sleep(100);
                count++;
            } catch(InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release();
            }
        }
        
    }

    除了能实现互斥锁,信号量还可以做到允许多个线程访问同一个临界区,这是它与互斥锁一个较大的区别点。

    将代码进行修改,实现限流功能:

    package constxiong.interview;
    
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * 测试使用信号量实现限流的效果
     * @author ConstXiong
     * @date 2019-12-18 14:18:47
     */
    public class TestSemaphore {
        
        private static AtomicInteger acount = new AtomicInteger(0);
        
        private static Semaphore semaphore = new Semaphore(10); 
        
        public static void main(String[] args) {
            testAddAtomic();
        }
        
        /**
         * 测试允许十个线程并发递增 acount
         */
        private static void testAddAtomic() {
            for (int i = 0; i < 100; i++) {
                new Thread(() -> {
                    System.out.println(addAtomic());
                }).start();
            }
        }
        
        private static int addAtomic() {
            try {
                semaphore.acquire();
                Thread.sleep(100);
                return acount.incrementAndGet();
            } catch(InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release();
            }
            return -1;
        }
        
    }

    在实际的 Java 开发中,信号量的使用相对互斥锁来说较少,知名度没那么高,但在其他编程语言中使用较广。


    原文链接
     


     

  • 相关阅读:
    Luogu P1462 通往奥格瑞玛的道路
    数据结构学习笔记——图的应用(最短路径和关键路径)
    数据结构学习笔记——特殊矩阵的压缩存储
    数据结构学习笔记——线性表
    图像分类综述—A survey on Semi-, Self- and Unsupervsed Techniques in Image Classification Similarities, Differences & Combinations
    目标检测综述
    操作系统学习
    Git官网下载太慢解决方法
    阿里云2020上云采购季,你最pick哪个产品组合?
    任务不再等待!玩转DataWorks资源组
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/12065843.html
Copyright © 2020-2023  润新知