用信号量机制实现吃冰淇淋问题

用信号量机制实现吃冰淇淋问题:桌子上有一只盘子,最多可容纳两个冰淇淋,每次只能放入或者取出一个冰淇淋。男厨师专门向盘子中放巧克力冰淇淋,女厨师专门向盘子中放抹茶冰淇淋,两个男顾客专门等待吃盘子中的巧克力冰淇淋,两个女顾客专门等吃盘子中的抹茶冰淇淋(JAVA代码实现)


具体代码实现如下

package SemIceCream01;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemIce01 {
	private static final int PLATE = 1;//一个盘子
	private static final int EMPTY = 2;//空缓冲区数量,初始为2
	private static final int FULL = 0;//满缓冲区数量,初始为0
	private static final int ICE_CHOCOLATE = 0;//巧克力冰淇淋个数,初始为0
	private static final int ICE_MATCHA = 0;//抹茶冰淇淋个数,初始为0
	//多线程共享的可操作数据,可视为临界资源
	static int ic=0;//巧克力冰淇淋
    static int im=0;//抹茶冰淇淋
	public static void main(String[] args) {
		//创建信号量
		Semaphore plate=new Semaphore(PLATE);
		Semaphore empty=new Semaphore(EMPTY);
		Semaphore full=new Semaphore(FULL);
		Semaphore iceChocolate=new Semaphore(ICE_CHOCOLATE);
		Semaphore iceMatcha=new Semaphore(ICE_MATCHA);
		//创建线程池
		ExecutorService ThreadPool = Executors.newFixedThreadPool(6);
		//在线程池中执行任务
		ThreadPool.execute(new CookThread(plate, full, empty, iceChocolate, 1));
		ThreadPool.execute(new CookThread(plate, full, empty, iceMatcha, 2));
		ThreadPool.execute(new CustomerThread(plate, full, empty, iceChocolate, 1));
		ThreadPool.execute(new CustomerThread(plate, full, empty, iceChocolate, 2));
		ThreadPool.execute(new CustomerThread(plate, full, empty, iceMatcha, 3));
		ThreadPool.execute(new CustomerThread(plate, full, empty, iceMatcha, 4));
		//关闭线程池
		ThreadPool.shutdown();
		
		
	}

}
class CookThread extends Thread{
	// 信号量
	 private volatile Semaphore plate; 
	 private volatile Semaphore full;    
	 private volatile Semaphore empty;    
	 private volatile Semaphore chocolate; 
	 //几号厨师
	 private int i;
	 
	 public CookThread(Semaphore plate,Semaphore full,Semaphore empty,Semaphore Chocolate,int i) {
		this.plate=plate;
		this.full=full;
		this.empty=empty;
		this.chocolate=Chocolate;
		this.i=i;
		 
	}
	@Override
	public void run() {
		while(true) {
			try {
				empty.acquire();//根据判断有无容量决定是否继续后面的工作
				/*若不加这行,也就意味着两个厨师可同时放冰淇淋,或在厨师放的同时,顾客吃等*/
				plate.acquire();	//P操作,信号量-1
				if(i==1){
					SemIce01.ic++;
					System.out.println("男厨师向盘子中放入巧克力冰淇淋,\t当前有"+(SemIce01.ic+SemIce01.im)+
							"个冰淇淋,\t其中巧克力冰淇淋有"+SemIce01.ic+"个,\t抹茶冰淇淋有"
							+SemIce01.im+"个");
				}
				if(i==2) {
					SemIce01.im++;
					System.out.println("女厨师向盘子中放入抹茶冰淇淋,\t当前有"+(SemIce01.ic+SemIce01.im)+
							"个冰淇淋,\t其中巧克力冰淇淋有"+SemIce01.ic+
							"个,\t抹茶冰淇淋有"+SemIce01.im+"个");
				}					
				//Thread.sleep(2000);采用随机数效果是否更好
				Thread.sleep((long) (Math.random() * 1000));
			} catch (InterruptedException e) {
				// TODO: handle exception
				e.printStackTrace();
			}finally {
				plate.release();//V操作,信号量+1
				full.release();//信号量+1
				chocolate.release();			
			}
		}
	}
}
class CustomerThread extends Thread{
	// 信号量
	 private volatile Semaphore plate; 
	 private volatile Semaphore full;    
	 private volatile Semaphore empty;    
	 private volatile Semaphore chocolate; 
	 //几号顾客
	 private int i;
	 public CustomerThread(Semaphore plate,Semaphore full,Semaphore empty,Semaphore Chocolate,int i) {
		this.plate=plate;
		this.full=full;
		this.empty=empty;
		this.chocolate=Chocolate;
		this.i=i;
		 
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true) {
			try {
				full.acquire();//根据是否有满缓冲区决定是进行后面的工作还是等待
				chocolate.acquire();//根据是否有对应的冰淇淋决定是进行后面的工作还是等待
				plate.acquire();					
				
				if(i<3) {
					SemIce01.ic--;
					System.out.println("男顾客"+i+"号吃掉一个巧克力冰淇淋,\t"
							+ "当前有"+(SemIce01.ic+SemIce01.im)+"个冰淇淋,\t其中巧克力冰淇淋有"
							+SemIce01.ic+"个,\t抹茶冰淇淋有"+SemIce01.im+"个");
				}
				else {
					SemIce01.im--;
					System.out.println("女顾客"+(i-2)+"号吃掉一个抹茶冰淇淋,\t当前有"+
							(SemIce01.ic+SemIce01.im)+"个冰淇淋,\t其中巧克力冰淇淋有"+
							SemIce01.ic+"个,\t抹茶冰淇淋有"+SemIce01.im+"个");
				}
				//Thread.sleep(2000);采用随机数效果是否更好
				Thread.sleep((long) (Math.random() * 1000));
			} catch (InterruptedException e) {
				// TODO: handle exception
				e.printStackTrace();
			}finally {
				plate.release();
				empty.release();
			}
		}
	}
}

参考如下:

《计算机操作系统》(第四版)p53 2.4.3信号量机制        p60 2.5.1.1利用记录型信号量解决生产者-消费者问题

Java之 Semaphore信号量的原理和示例

Java并发编程:volatile关键字解析


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值