java设计模式10 ---- 生产者-消费者模式[线程]

需求: 模拟两个 /多个 线程的--沟通协作(一个生产者线程, 一个消费者线程), 如何保证他们正常通信?

一, 两个线程的通信


角色1--两个线程的工作目标: 中间物

/**
 * 角色: 
 * 1,中间物: name, falg
 * 2,生产者: flag, 中间物, getName()
 * 3,消费者: flag, 中间物, setName()
 * @author wang
 *
 */

public class Food {
	//属性
	private String status;
	private boolean isSetted;
	//构造
	public Food(String status) {
		this.status = status;
	}
	
	//方法1
	//get(),set()
	public synchronized void showName() {
		
		//判断p是否--isSetted
		if(isSetted) {
			System.out.println(Thread.currentThread().getName()+"say: "+status);
			isSetted=false;//更换p的状态
			notify();//通知生产者--可以生产了
		}
		else {
			try {
				wait();//休息等待
			} catch (InterruptedException e) {
			}
		}
	}
	
	int i=0;
	public synchronized void setName() {
		
		//判断是否: isSetted
		if(isSetted) {
			try {
				wait();//休息等待
			} catch (InterruptedException e) {
			}
		}
		else {
			System.out.println(Thread.currentThread().getName()+"start work...\n\n");
			//赋值
			if(i++ %2==0) {
				status="food status--too salty !!!";
			}else {
				status="food status--too sweaty !";
			}
			isSetted=true;//更换p的状态
			notify();//通知其他线程--可以访问了
		}//else
	}
}

角色2: 生产者线程

public class Producer implements Runnable {
	//属性
	private Food p;
	//构造
	public Producer(Food p) {
		this.p = p;
	}
	
	@Override
	public void run() {
		while(true)
		p.setName();
	}
}

角色3: 消费者线程

public class Consumer implements Runnable {
	//属性
	private Food p;
	
	//构造
	public Consumer(Food p) {
		this.p = p;
	}
	
	@Override
	public void run() {
		while(true)
		p.showName();
	}
}

测试类

public class Test {
	public static void main(String[] args) {
		Food p = new Food("a");
		Producer pro = new Producer(p);
		Consumer cons = new Consumer(p);
		
		//启动线程
		new Thread(pro,"生产者").start();
		new Thread(cons,"消费者").start();
	}
}

==========截图验证=======



二, 多个线程的通信

角色1:  所有线程--作用的对象(中间物): Food

/**
 *1,定义"菜" class: make(), clear()
 *2,定义生产者 class implements Runnable:  run(  菜.make()  ) 
 *3,定义消费者 class implements Runnable:  run(  菜.clear() )

 * 为了便于观察:  消费--生产线程: 的效果, 此处使用死循环--来多次操作
 * "游戏"规则:
 *  1, 顾客	 一次吃   1个food 
 *  2, 生产者 一次make 2个food
 * @author wang
 *
 */
public class Food {
	//属性
	int foodCount;//food总数量
	//构造
	public Food(int foodCount) {
		this.foodCount = foodCount;
	}
	
	//方法1,对外提供的调用"接口": 如何制作菜
	public synchronized void make() throws InterruptedException {
		if(foodCount<5) {
			int former=foodCount;
			foodCount+=2;
			System.out.println("\t foodCount="+former+",\t "+Thread.currentThread().getName()+"  又生产了2个food ! ==>foodCount="+foodCount);
			this.notify();//通知顾客来吃
		}
		else {//休息等待
			this.wait();
		}
	}
	
	//方法2,//对外提供的调用"接口": 如何销毁菜
	public synchronized void clear() throws InterruptedException {
		if(foodCount!=0) {
			int former=foodCount;
			foodCount--;
			Thread.sleep(1000);//1s 消灭 一个
			System.out.println("foodCount="+former+",\t "+Thread.currentThread().getName()+" 又消灭了1个food ! ==>foodCount="+foodCount);

			this.notify();//通知生产者--已经吃完1个了
		}
		else {
			this.wait();
		}
	}

}

角色2:  生产者线程

public class Producer implements Runnable {
	//属性
	private Food f;
	
	//构造
	public Producer(Food f) {
		this.f = f;
	}

	@Override
	public void run() {
		
		while(true) //一直调方法
			try {
				f.make();
			} catch (InterruptedException e) {
			}
	}
}

角色3:  消费者线程

public class Consumer implements Runnable {
	//属性
	Food f;
	//构造
	public Consumer(Food f) {
		this.f = f;
	}

	
	@Override
	public void run() {
		while(true) //一直调方法
			try {
				f.clear();
			} catch (InterruptedException e) {
			}
	}
}

测试类: 创建多个生产者, 多个消费者

public class Test {
	public static void main(String[] args) {
		Food f = new Food(5);
		Producer sed1 = new Producer(f);
		Consumer sed2 = new Consumer(f);
		
		Thread p1 = new Thread(sed1,"生产者1");
		Thread p2 = new Thread(sed1,"生产者2");
		Thread c1 = new Thread(sed2, "消费者1");
		Thread c2 = new Thread(sed2, "消费者2");
		Thread c3 = new Thread(sed2, "消费者3");
		Thread c4 = new Thread(sed2, "消费者4");
		Thread c5 = new Thread(sed2, "消费者5");
		
		//
		p1.start();
		p2.start();
		c1.start();
		c2.start();
		c3.start();
		c4.start();
		c5.start();
	}
}
=========效果截图=======



猜你喜欢

转载自blog.csdn.net/eyeofeagle/article/details/80955759