(九)Java入门--多线程(5)线程通信--多生产者多消费者


代码实例(参考代码:TreadCom3.java)

/*多生产者多消费者
生产一个馒头就消费一个馒头
两个线程生产馒头,两个线程消费馒头
*/
class Resource3 {   //公共资源
    private String name;
    private int count = 0;
    private boolean flag = false;

    private void setName(String name) {
        this.name = name;
        count++;
    }

    //生产方法
    public synchronized void producer() {
        // if(flag)  //有馒头就等待
        while (flag) { //备注问题1
            try {
                this.wait();
            } catch (InterruptedException e) {
            }
        }

        setName("馒头");
        System.out.println(name + "...生产者..." + count);
        notifyAll();
        flag = true;
    }

    //消费方法
    public synchronized void consumer() {
        //if(!flag)  //没有馒头就等待
        while (!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
            }
        }
        System.out.println(name + "...消费者..." + count);
        notifyAll(); //备注问题2
        flag = false;

    }
}

//生产线程
class TreadPro implements Runnable {
    private Resource3 r;

    TreadPro(Resource3 r) {
        this.r = r;
    }
    //生产方法
    public void run() {
        while (true) {
            r.producer();
        }
    }

}
//消费线程
class TreadCon implements Runnable {
    private Resource3 r;

    TreadCon(Resource3 r) {
        this.r = r;
    }
    //消费方法
    public void run() {
        while (true) {
            r.consumer();
        }
    }
}


public class TreadCom3 {

    public static void main(String[] args) {
        //同一资源
        Resource3 r = new Resource3();
        //不同任务
        TreadPro p = new TreadPro(r);
        TreadCon c = new TreadCon(r);
        //多个线程,两个生产,两个消费
        Thread t0 = new Thread(p);
        Thread t1 = new Thread(p);
        Thread t2 = new Thread(c);
        Thread t3 = new Thread(c);
        t0.start();
        t1.start();
        t2.start();
        t3.start();

    }
}

输出结果:
。
。
。
馒头...生产者...44187
馒头...消费者...44187
馒头...生产者...44188
馒头...消费者...44188
馒头...生产者...44189
馒头...消费者...44189
。
。
。

问题备注说明:
1、问题:用if只判断一次,如果线程0和线程1都在线程池,然后线程0被唤醒执行之后,接着又唤醒了线程1,这样就造成了生产多个馒头的情况。
解决办法:需要在线程1醒来之后在去判断一下标志位(while)。
2、问题:用while时,如果出现消费的线程都在线程池内,并生产线程0在线程内,线程1执行完后唤醒的是线程0那么线程0也会立即进入到线程池中,所以,导致所有线程都在线程池中,造成死锁。
解决办法:进行所有线程唤醒动作notifyAll();。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值