• Semaphore,动态增减信号量


    我的理解~~

    【信号量】:

    • 用于控制对某资源访问的同一时间的并发量。

    【如何获取】:

    • semaphore.tryAcquire(),尝试获取,不阻塞
    • semaphore.acquire(),没信号量可用时,将进行阻塞等

    【如何释放】:

    • semaphore.release();
    • 线程抛出各种异常,都别忘了在finally中释放信号量;
    • 如果释放的比获取的信号量还多,例如获取了2个,释放了5次,那么当前信号量就动态的增加为5了,要注意。

    【动态增加】:

    • 多释放几次,就可以达到信号量动态增加的效果了

    【动态减小】:

    • 信号量本来有这个api的,不过是protected方法,所以我们需要显式继续Semaphore,并重新实现该api,见ResizeableSemaphore类中的reducePermits(int reduction);
    • 举例如下:(该表格有个假设前提,不存在多余的release而产生出新的信号量,即release次数<=acquire次数)
    当前信号量A
    (A=A1+A2)
    占用信号量A1 可用信号量A2 重新设置信号量B
    (B=B1+B2)
    当前可用的信号量B1 当前待释放的量B2
    5 3 2 3 0 0
    5 3 2 1 0 -2
    5 3 2 9 6 0

    image

    【动态减小—demo】:

    import java.util.concurrent.Semaphore;
     
     
    public class AdjustableSemaphore {
     
        private final ResizeableSemaphore  semaphore = new ResizeableSemaphore();
        
        private int maxPermits = 0;
        
        public AdjustableSemaphore(){
            
        }
        
        synchronized void setMaxPermits(int newMax){
            if(newMax < 1){
                throw new IllegalArgumentException("Semaphore size must be at least 1,"
                    + " was " + newMax);
            }
            
            int delta = newMax - this.maxPermits;
            
            if(delta == 0){
                return ;
            }else if(delta > 0){
                this.semaphore.release(delta);
            }else {
                delta *= -1;
                this.semaphore.reducePermits(delta);
            }
            
            this.maxPermits = newMax;
            
        }
        
        public int availablePermits(){
           return this.semaphore.availablePermits();
        }
        
        public void release(){
            this.semaphore.release();
        }
        
        public boolean tryAcquire(){
            return this.semaphore.tryAcquire();
        }
        
        
        
        
        private static final class ResizeableSemaphore extends Semaphore {
     
            ResizeableSemaphore(){
                super(0);
            }
            
            @Override
            protected void reducePermits(int reduction){
                super.reducePermits(reduction);
            }
            
        }
        
        
    }
     
     
    【测试程序】:
    AdjustableSemaphore semaphore = new AdjustableSemaphore();
            System.out.println("==============5");
            semaphore.setMaxPermits(5);
            
            for(int i=0;i<20;i++){
                semaphore.tryAcquire();
            }
            
            
            System.out.println(semaphore.availablePermits()); //5个信号量全被占用,所以当前可用的为0
            
            
            System.out.println("==============2");
            semaphore.setMaxPermits(2);
            
            System.out.println(semaphore.availablePermits()); //将信号量显式设置为2,与上一步合并结果(2-5)=-3,表示目前有5个被占用,信号量只有2,所以还有3个欠着待释放
            
            
            System.out.println("==============20");
            semaphore.setMaxPermits(20);
            System.out.println(semaphore.availablePermits());//将信号量显式设置为20,与上一步合并结果(20-2)+(-3)=15个,表示目前还有15个可用。
            
            System.out.println("==============3");
            semaphore.setMaxPermits(3);
            System.out.println(semaphore.availablePermits());//同上,(3-20)+15=-2
            
            System.out.println("==============1");
            semaphore.setMaxPermits(1);
            System.out.println(semaphore.availablePermits());//同上,(1-3)-2=-4
            
            System.out.println("==============10");
            semaphore.setMaxPermits(10);
            System.out.println(semaphore.availablePermits());//同上,(10-1)-4=5
            
            System.out.println("==============FINALLY");
            for(int i=0;i<7;i++){
                semaphore.release();
            }
            System.out.println(semaphore.availablePermits());//释放了7个,所以7+5=12,虽然显式设置了信号量为10,但因多release()了两次,所以无意之中隐式增大了信号量。
     
     
     
    【输出结果】:

    ==============5
    0
    ==============2
    -3
    ==============20
    15
    ==============3
    -2
    ==============1
    -4
    ==============10
    5
    ==============FINALLY
    10

    这里可参考:http://blog.teamlazerbeez.com/2009/04/20/javas-semaphore-resizing/

  • 相关阅读:
    分页
    IBM TAM手册
    单点登录集成商。
    Using Web Services Instead of DCOM
    symantec endpoint protection SEP禁用所有usb设备,只允许部分例外
    桌面管理landesk太古案例
    AdventureWorks数据库的安装和NorthWind例子数据库下载
    IBM Tivoli Access Manager for ebusiness 6.1.1 Administration and Deployment
    word编辑长文档方法
    笔记本电源消耗测量
  • 原文地址:https://www.cnblogs.com/alipayhutu/p/2518620.html
Copyright © 2020-2023  润新知