黑马程序员技术交流社区

标题: 各位高手 又有问题 关于生产者消费者经典模式的 [打印本页]

作者: kira    时间: 2014-1-22 17:27
标题: 各位高手 又有问题 关于生产者消费者经典模式的
复习过程中 发现出了不少问题啊
温故而知新 可以为师矣 这句话说得太对了
我就说正题
我现在写了一个经典的消费 生成模式
我还是采用的for循环 因为while循环这个玩不好 机子就死掉 伤不起
public class CommodityDemo {

        /**
         * @param args
         */
        public static void main(String[] args) {
                Commodity c = new Commodity();
                new Thread(new Produce(c)).start();
                new Thread(new Consumer(c)).start();
        }

}
class Commodity{
        private String name;
        private int count=1;
        private boolean flag=false;
        public synchronized void set(String name){
                this.name = name+"----"+count++;
                if(flag){
                        try {
                                this.wait();
                        } catch (InterruptedException e) {
                               
                               
                        }
                System.out.println(Thread.currentThread().getName()+"生产者"+this.name);
               
               
                }
                else{
                        this.notify();
                        flag =true;
                       
                }
                }
        public synchronized void out(){
                if(!flag){
                        try {
                                this.wait();
                        } catch (InterruptedException e) {
                               
                               
                        }
                System.out.println(Thread.currentThread().getName()+"消费者"+this.name);
               
               
                }
                else{
               
                        this.notify();
                        flag = false;
                }
        }
       
       
       
}
class Produce implements Runnable{
       
         private  Commodity com;
        Produce(Commodity com){
        this.com =com;
        }
        @Override
        public void run() {
                for(int x =0;x<20;x++){
                        com.set("商品");
                       
                       
                }
       
               
        }
       
       
       
}
class Consumer implements Runnable{
       
        private  Commodity com;
        Consumer(Commodity com){
        this.com =com;
        }
        @Override
        public void run() {
                for(int y=0;y<20;y++){
                        com.out();
                       
                }
               
        }
       
       
       
       
       
}

这里同步都加好了 是消费一个生产一个的 结果 发现
出现
Thread-0生产者商品----2
Thread-0生产者商品----4
Thread-1消费者商品----6
Thread-0生产者商品----6
Thread-1消费者商品----8
这样的情况 请问大神 这是什么原因 怎样修改{:soso_e136:}

作者: kira    时间: 2014-1-22 21:34
{:soso_e136:} 别沉啊
作者: panzhenglian    时间: 2014-1-23 00:24
本帖最后由 panzhenglian 于 2014-1-23 00:26 编辑

判断标记那里有很大错误,标记为假时,如果代表没有商品,应该输出生产才对,可是代码却执行到else,直接将标记改为真,就等于商品没有生产就改变了商品的状态,如果标记为假代表有商品,应该wait一下的,可是代码却是执行后面改变标记,简单的修改了一下楼主的代码
  1. class CommodityDemo{

  2.         public static void main(String[] args) {
  3.                 Commodity c = new Commodity();
  4.                 new Thread(new Produce(c)).start();
  5.                 new Thread(new Consumer(c)).start();
  6.         }
  7. }
  8. class Commodity {
  9.         private String name;
  10.         private int count = 1;
  11.         private boolean flag = false;
  12.        
  13.         public synchronized void set(String name) {
  14.                        
  15.                 while (flag)
  16.                         try {this.wait();} catch (InterruptedException e) {}
  17.                 this.name = name + "----" + count;
  18.                 System.out.println(Thread.currentThread().getName() + "生产者"+ this.name);       
  19.                 count++;
  20.                 flag=true;
  21.                 this.notify();
  22.         }
  23.         public synchronized void out() {
  24.                 while(!flag)
  25.                         try {this.wait();} catch (InterruptedException e){}
  26.                 System.out.println(Thread.currentThread().getName() + "消费者"+ this.name);       
  27.                 flag=false;
  28.                 this.notify();
  29.         }
  30. }
  31. class Produce implements Runnable {
  32.         private Commodity com;
  33.         Produce(Commodity com) {
  34.                 this.com = com;
  35.         }
  36.         public void run() {
  37.                 for (int x = 0; x < 20; x++) {
  38.                         com.set("商品");
  39.                 }
  40.         }
  41. }
  42. class Consumer implements Runnable {
  43.         private Commodity com;
  44.         Consumer(Commodity com) {
  45.                 this.com = com;
  46.         }
  47.         public void run() {
  48.                 for (int y = 0; y < 20; y++) {
  49.                         com.out();
  50.                 }
  51.         }
  52. }
复制代码




作者: kira    时间: 2014-1-23 10:37
panzhenglian 发表于 2014-1-23 00:24
判断标记那里有很大错误,标记为假时,如果代表没有商品,应该输出生产才对,可是代码却执行到else,直接将 ...

原来如此  话说大神 while循环那里 原来可以不用加大括号的啊  那他的那个循环范围就是到this.notify()那里么
比如set方法的那个flag判断循环那 :lol
作者: panzhenglian    时间: 2014-1-23 11:23
kira 发表于 2014-1-23 10:37
原来如此  话说大神 while循环那里 原来可以不用加大括号的啊  那他的那个循环范围就是到this.notify()那 ...

while循环不加括号只循环一行,就是这段代码的下一行,try那行,包括for循环和if也是,不加括号只能循环一段代码,我为了方便阅读这么写的,但是别误解while循环到下面notify才结束哦
作者: kira    时间: 2014-1-23 12:12
panzhenglian 发表于 2014-1-23 11:23
while循环不加括号只循环一行,就是这段代码的下一行,try那行,包括for循环和if也是,不加括号只能循环 ...

涨姿势了 :o 大神又上了一课




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2