需求: 模拟两个 /多个 线程的--沟通协作(一个生产者线程, 一个消费者线程), 如何保证他们正常通信?
一, 两个线程的通信
角色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();
}
}
=========效果截图=======