146_多线程(线程间通信-生产者消费者)

一个生产者一个消费者
class ProducerConsumer{
public static void main(String[] args){
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);

Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);

t1.start();
t2.start();
}
}

class Resource{
private String name;
private int count = 1;
private boolean flag = false;

public synchronized void set(String name){
if(flag)
try{wait();}catch(Exception e){}
this.name = name +"--"+count++;
System.out.println(Thread.currentThread().getName()+
"-生产者-"+this.name);
flag = true;
this.notify();
}

public synchronized void out(){
if(!flag)
try{wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+
"-消费者-"+this.name);
flag = false;
this.notify();
}
}

class Producer implements Runnable{
private Resource res;

Producer(Resource res){
this.res = res;
}
public void run(){
while(true){
res.set("+商品+");
}
}
}

class Consumer implements Runnable{
private Resource res;

Consumer(Resource res){
this.res = res;
}
public void run(){
while(true){
res.out();
}
}
}

两个生产者两个消费者。改动如下。
class ProducerConsumer{
public static void main(String[] args){
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);

Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);

t1.start();
t2.start();
t3.start();
t4.start();
}
}

运行结果会出现另外两种情况:
1.生产者生成了两次,消费者只取一次
2.生产者生成一次,消费者取两次
发生这两种情况是因为没有判断标记flag。需要将if(flag)改为while(flag)。
但只修改这点,会导致所有进程都处于全部等待状态。所以要把notify()改为notifyAll();
但是改为notifyAll()唤醒的是所有线程,即同时包括生产者和消费者。改进方法见下一篇笔记。

/*
对于多个生产者和消费者
为什么要定义while判断标记?
原因:让被唤醒的线程再进行一次标记判断

为什么定义notifyAll()?
因为需要唤醒对方线程。用notify()容易出现唤醒
本方线程的情况,导致程序中的所有线程都等待。
*/class ProducerConsumer{
public static void main(String[] args){
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);

Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);

t1.start();
t2.start();
t3.start();
t4.start();
}
}

class Resource{
private String name;
private int count = 1;
private boolean flag = false;

public synchronized void set(String name){
while(flag)
try{wait();}catch(Exception e){}
this.name = name +"--"+count++;
System.out.println(Thread.currentThread().getName()+
"-生产者-"+this.name);
flag = true;
this.notifyAll();
}

public synchronized void out(){
while(!flag)
try{wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+
"-消费者-"+this.name);
flag = false;
this.notifyAll();
}
}

class Producer implements Runnable{
private Resource res;

Producer(Resource res){
this.res = res;
}
public void run(){
while(true){
res.set("+商品+");
}
}
}

class Consumer implements Runnable{
private Resource res;

Consumer(Resource res){
this.res = res;
}
public void run(){
while(true){
res.out();
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值