Semaphore 信号量的简单应用

   信号量机制通常用于限制对某种资源的同时访问的线程数量。信号量机制是一中典型的同步机制,可以用于解决常用的线程同步问题。
    在java并发库中,类Semaphore可以实现信号量机制。定义如下
    public class Semaphore extends Object  implements Serializable
    一个信号量管理一个许可集合,可以通过方法acquire()获取一个许可,如果没有许可可以使用,则等待。通过方法release()可以释放一个许可。
    信号量的构造方法如下:
    Semaphore( int permits) ;//用给点给的许可数来创建一个Samephore对象。
    Semaphore(in permits,boolean fair)//用给定的许可数,创建Samephore对象,并可以设置公平参数fair。参数fair可以取值为true或false,指明当有许可使用时,是采用公平策略还是非公平策略来获取许可,
    公平策略可以保证每个都能获取许可,对于防止线程出现“饥饿”现象是由帮助的。
    例如:
    Semaphore available = new Semaphore(10,true); //表示创建了有是个许可的信号量 available,该信号量的获取策略是公平的。
    Semaphore available = new Semaphore(1);//表示创建了只有一个许可的信号量,它可以实现互拆锁的功能。    

    1)demo 示例:
    
    银行有4个窗口可以同时办理业务,现在有20个顾客需要办理业务,使用信号量机制模拟。
    
    //工作线程类
    public class Customer extends Thread{
        Semaphore counter;
        int id;
        int times;
        Coustomer (Semaphore counter,int id){
            this.counter = counter;
            this.id = id;
            times = (int)(Math.random() *Integer.MAX_VALUE);
        }
        public void run(){
            try{
                counter.acquire(); //获取许可
                System.out.println("第"+id + "尾顾客开始办理业务>>>>>>");
                for(int i=0;i<times;i++); //模拟了顾客办理业务的时间。。。
                System.out.println("第"+ id+ "位顾客已经办理完业务,准备离开>>>>>>");
                counter.release();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }
    //启动类
    public class Index{
        public static void main(String [] args){
            Semaphore counter = new Semaphore(4);
            Thread [] threads = new Thread[20];
            for(int i = 0;i<20;i++){
                threads[i] = new Coustomer(counter,i+1);
                threads[i].start();
            }        
        }
    }

运行结果:

第1位顾客开始办理业务>>>>>>
第4位顾客开始办理业务>>>>>>
第2位顾客开始办理业务>>>>>>
第3位顾客开始办理业务>>>>>>
第2位顾客已经办理完业务,准备离开>>>>>>
第4位顾客已经办理完业务,准备离开>>>>>>
第3位顾客已经办理完业务,准备离开>>>>>>
第5位顾客开始办理业务>>>>>>
第6位顾客开始办理业务>>>>>>
第7位顾客开始办理业务>>>>>>
第6位顾客已经办理完业务,准备离开>>>>>>
第5位顾客已经办理完业务,准备离开>>>>>>
第1位顾客已经办理完业务,准备离开>>>>>>
第7位顾客已经办理完业务,准备离开>>>>>>
第8位顾客开始办理业务>>>>>>
第9位顾客开始办理业务>>>>>>
第10位顾客开始办理业务>>>>>>
第10位顾客已经办理完业务,准备离开>>>>>>
第8位顾客已经办理完业务,准备离开>>>>>>
第9位顾客已经办理完业务,准备离开>>>>>>
第11位顾客开始办理业务>>>>>>
第14位顾客开始办理业务>>>>>>
第13位顾客开始办理业务>>>>>>
第13位顾客已经办理完业务,准备离开>>>>>>
第12位顾客开始办理业务>>>>>>
第15位顾客开始办理业务>>>>>>
第14位顾客已经办理完业务,准备离开>>>>>>
第11位顾客已经办理完业务,准备离开>>>>>>
第16位顾客开始办理业务>>>>>>
第16位顾客已经办理完业务,准备离开>>>>>>
第15位顾客已经办理完业务,准备离开>>>>>>
第12位顾客已经办理完业务,准备离开>>>>>>
第18位顾客开始办理业务>>>>>>
第19位顾客开始办理业务>>>>>>
第19位顾客已经办理完业务,准备离开>>>>>>
第17位顾客开始办理业务>>>>>>
第18位顾客已经办理完业务,准备离开>>>>>>
第20位顾客开始办理业务>>>>>>
第17位顾客已经办理完业务,准备离开>>>>>>
第20位顾客已经办理完业务,准备离开>>>>>>

 

2)demo 示例:

    使用信号量  使用只有一个许可的信号量作为锁,实现同步控制。
    
    public class Data{
        
        int a = 0;
        int b = 0;
        Semaphore semaphore;
        
        Data( Semaphore semaphore){
            this.semaphore = semaphore;
        }
        //增加1
        public void increase(){
            try{
                semaphore.acquire();        
                a++;
                b++;
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            semaphore.release();
        }
        //验证
        public void isEqual(){
            try{
                semaphore.acquire();
                System.out.println("a = " + a + "\tb" + "b = "  + b + "\t" + (a==b) );
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            semaphore.release();
        }
    }
    
    //线程工作类
    public class Worker implements Runnable{
        private Data data;
        Worker(Data data){
            this.data = data;
        }
        public void run(){
        
        while(true){
            data.increase();
        }
    }
    //启动类
    public class Index{
        public static  void main(String [] args){
            Semaphore semaphore = new Semaphore(1);
            Data data = new Data( semaphore );
            Worker worker1 = new Worker( data);
            Worker worker2 = new Worker(data);
            Thread t1 = new Thread( worker1);
            Thread t2 = new Thread( worker2);
            t1.start();
            t2.start();
            while(true){
                data.isEqual();
                try{
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }    
    }

 

运行结果:

a = 0    b = 0    true
a = 26223538    b = 26223538    true
a = 51329669    b = 51329669    true
a = 77307542    b = 77307542    true
a = 102215781    b = 102215781    true
a = 127411276    b = 127411276    true
a = 152337489    b = 152337489    true
a = 178239099    b = 178239099    true

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值