信号量Semaphore

Semaphore可以控制某个资源可被同时访问的个数,通过  acquire()  获取一个许可,如果没有就等待,而  release()  释放一个许可。
入门例子
semaphoreClass.java

import java.util.concurrent.Semaphore;

public class semaphoreClass {

   final static Semaphore semp = new Semaphore(5);

}


TestSemaphore.java

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class TestSemaphore {

   public static void main(String[] args){

      ExecutorService exec = Executors.newCachedThreadPool();

      for(int i = 0;i<20;i++){

         exec.execute(new SemaphoreThread(i));

      }

      exec.shutdown();

   }

}

class SemaphoreThread implements Runnable{

   int NO;

   public SemaphoreThread(int NO){

      this.NO = NO;

   }

   public void run() {

      try {

         semaphoreClass.semp.acquire();

         System.out.println("Accessing: " + NO);

         Thread.sleep((long) (Math.random() * 10000));

         semaphoreClass.semp.release();

            System.out.println("-------"+semaphoreClass.semp.availablePermits());

            } catch (InterruptedException e) {

              e.printStackTrace();

              }

      }

   }

 

经典例子

1、生产者消费者

import java.util.concurrent.Semaphore;

public class Sema {

   static Semaphore empty=new Semaphore(10); //信号量:记录仓库空的位置

   static Semaphore full=new Semaphore(0);   //信号量:记录仓库满的位置 

   static Semaphore mutex=new Semaphore(1);  //临界区互斥访问信号量

}


public class Producer implements Runnable{

   public void run(){

      try{

         while(true){

            Sema.empty.acquire(); //递减仓库空信号量    

            Sema.mutex.acquire(); //进入临界区    

            System.out.println("生成一个产品放入仓库");    

            Sema.mutex.release(); //离开临界区   

            Sema.full.release();  //递增仓库满信号量    

            Thread.currentThread().sleep(100);

         }

      }catch (InterruptedException e){}

   }

}


public class Consumer implements Runnable{

   public void run(){

      try{

         while(true){

            Sema.full.acquire();

            Sema.mutex.acquire();

            System.out.println("从仓库拿出一个产品消费");

            Sema.mutex.release();

            Sema.empty.release();

            Thread.currentThread().sleep(1000);

            }

         }catch (InterruptedException e) {}

      }

}


public class Test {

   public static void main(String[]args){

      Producer producer = new Producer();

      Consumer consumer = new Consumer();

      new Thread(new Producer()).start();

      new Thread(new Consumer()).start();

   }

}


2、哲学家进餐问题

import java.util.concurrent.Semaphore;

public class Sema {

   static int[]status = new int[5];//哲学家状态,0表示思考,1表示进餐

   static Semaphore[]s = null;//信号量,记录哲学家是否可以进餐

   static Semaphore mutex = new Semaphore(1);//用作互斥信号量

   //初始化哲学家进餐信号量,默认都不能进餐

   static{

      s = new Semaphore[5];

      for(int i = 0;i<s.length;i++){

         s[i] = new Semaphore(0);

      }

   };

}


public class Philosopher implements Runnable{

   private int pid;//当前哲学家的序号

   private int lid;//坐在左手边的哲学家序号

   private int rid;//坐在右手边的哲学家序号

   public Philosopher(int id) {

      this.pid = id;

      this.lid = (id+4)%5;

      this.rid = (id+1)%5;

   }

   private void test(int pid){

      //如果左右两边都没进餐则可以进餐

      if(Sema.status[pid]==0&&Sema.status[lid]==0&&Sema.status[rid]==0){

         Sema.status[pid] = 1;

         Sema.s[pid].release();

      }

   }

   public void run(){

      while(true){

         try {

            Sema.mutex.acquire();

            test(pid);

            Sema.mutex.release();

            Sema.s[pid].acquire();

            System.out.println("#"+pid+"号哲学家正在进餐");

            Sema.mutex.acquire();

            Sema.status[pid] = 0;

            test(lid);

            test(rid);

            Sema.mutex.release();

         } catch (InterruptedException e) {e.printStackTrace();}

      }

   }

}


public class Test {

   public static void main(String[]args){

      new Thread(new Philosopher(0)).start();  

      new Thread(new Philosopher(1)).start();  

      new Thread(new Philosopher(2)).start();  

      new Thread(new Philosopher(3)).start();  

      new Thread(new Philosopher(4)).start();

   }

}


3、读者写者问题

import java.util.concurrent.Semaphore;

public class Sema {

   static Semaphore db = new Semaphore(1);

   static Semaphore mutex = new Semaphore(1);

   static int num = 0;//记录正在读或想要读的进程数

}


public class Reader implements Runnable{

   public void run(){

      while(true){

         try{

            Sema.mutex.acquire();

            Sema.num++;

            if(Sema.num==1)

                Sema.db.acquire();

            Sema.mutex.release();

            System.out.println(Thread.currentThread().getName()+" is reading");

            Thread.sleep(500);

            Sema.mutex.acquire();

            Sema.num--;

            if(Sema.num==0)

                Sema.db.release();

            Sema.mutex.release();

            Thread.sleep(400);

         }catch (Exception e) {}

      }

   }

}


public class Writer implements Runnable{

   public void run(){

      while(true){

         try {

            Sema.db.acquire();

            System.out.println(Thread.currentThread().getName()+" is writting");

            Thread.sleep(1000);

            Sema.db.release();

            Thread.sleep(400);

         } catch (InterruptedException e) {}

      }

   }

}


4、理发师









版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://my.oschina.net/u/1987489/blog/491332

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值