程序://用JAVA中的多线程示例生产者和消费者问题 
/*
 生产者与消费者模型中,要保证以下几点:
1 同一时间内只能有一个生产者生产
2 同一时间内只能有一个消费者消费
3 生产者生产的同时消费者不能消费
4 消息队列满时生产者不能继续生产
5 消息队列空时消费者不能继续消费
 */
class Producer implements Runnable 

private SyncStack stack;     public Producer(SyncStack stack) { 
    this.stack = stack; 
}     public void run() { 
      for (int i = 0; i < stack.getProducts().length; i++) { 
          String product = "产品"+i; 
          stack.push(product); 
          System.out.println("生产了: "+product); 
          try 
          { 
            Thread.sleep(20); 
          } 
          catch(InterruptedException e) 
          { 
            e.printStackTrace(); 
          } 
      } 
    }     
} class Consumer implements Runnable 

    private SyncStack stack;     public Consumer(SyncStack stack) { 
    this.stack = stack; 

    public void run() { 
      for(int i=0;i <stack.getProducts().length;i++) 
          { 
          String product =stack.pop(); 
          System.out.println("消费了: "+product); 
          try 
          { 
            Thread.sleep(1000); 
          } 
          catch(InterruptedException e) 
          { 
            e.printStackTrace(); 
          }           }       
    } 

class SyncStack 

    private String[] products = new String[10];
    private int index; 
    public synchronized void push(String product) 
    { 
      if(index==product.length()) 
      { 
          try { 
              wait(); 
          } catch (InterruptedException e) { 
              // TODO Auto-generated catch block 
              e.printStackTrace(); 
          } 
      } 
      notify(); 
      products[index]=product; 
      index++; 
    } 
    
    public synchronized String pop() 
    { 
      if(index==0) 
      { 
          try { 
              wait(); 
          } catch (InterruptedException e) { 
              // TODO Auto-generated catch block 
              e.printStackTrace(); 
          } 
      } 
      notify(); 
      index--; 
      String product = products[index]; 
      return product; 
    }     public String[] getProducts() { 
      return products; 
    } 

public class Producer_Customer { 
    
    public static void main(String[] args) { 
      SyncStack stack=new SyncStack(); 
      Producer p=new Producer(stack); 
      Consumer c=new Consumer(stack);       new Thread(p).start(); 
      new Thread(c).start(); 
      } 
    } 结果一:
生产了: 产品0
消费了: 产品0
生产了: 产品1
生产了: 产品2
生产了: 产品3
消费了: 产品3
生产了: 产品4
消费了: 产品4
生产了: 产品5
消费了: 产品5
生产了: 产品6
消费了: 产品6
生产了: 产品7
消费了: 产品7
生产了: 产品8
消费了: 产品8
生产了: 产品9
消费了: 产品9
消费了: 产品2
消费了: 产品1这个结果我能理解。结果二:
生产了: 产品0
消费了: 产品0
生产了: 产品1
生产了: 产品2
生产了: 产品3
消费了: 产品3
生产了: 产品4
生产了: 产品5
消费了: 产品4
消费了: 产品5
生产了: 产品6
消费了: 产品6
生产了: 产品7
消费了: 产品7
生产了: 产品8
消费了: 产品8
生产了: 产品9
消费了: 产品9
消费了: 产品2
消费了: 产品1这个结果有些疑问:
在产品4和产品5生成出来后
应该是先消费5,再消费4才对啊
怎么是:
消费了: 产品4
消费了: 产品5结果三:
生产了: 产品0
消费了: 产品0
生产了: 产品1
生产了: 产品2
生产了: 产品3
消费了: 产品3
生产了: 产品4
消费了: 产品4
生产了: 产品5
消费了: 产品5
生产了: 产品6
生产了: 产品7
消费了: 产品6
消费了: 产品7
生产了: 产品8
消费了: 产品8
生产了: 产品9
消费了: 产品9
消费了: 产品2
消费了: 产品1问题同结果二,
出在
生产了: 产品6
生产了: 产品7
消费了: 产品6
消费了: 产品7
大家帮我解释下

解决方案 »

  1.   

    是不是因为你的打印是在两个线程里处理,而不是在同步方法里处理,这样他们调用System.out并没有同步。
      

  2.   

    你的push 和打印 以及 pop和打印没同步
    也就是说,消费的顺序是 5,4,但打印顺序却是4,5
    你可以把打印输出放到你的push(pop)方法里,这样就可以了
     
    如下package ProducerConsumer;
    //用JAVA中的多线程示例生产者和消费者问题 
    /* 
    生产者与消费者模型中,要保证以下几点: 
    1 同一时间内只能有一个生产者生产 
    2 同一时间内只能有一个消费者消费 
    3 生产者生产的同时消费者不能消费 
    4 消息队列满时生产者不能继续生产 
    5 消息队列空时消费者不能继续消费 
    */ 
    class Producer implements Runnable 

    private SyncStack stack;     public Producer(SyncStack stack) { 
        this.stack = stack; 
    }     public void run() { 
          for (int i = 0; i < stack.getProducts().length; i++) { 
              String product = "产品"+i; 
              stack.push(product); 
              //System.out.println("生产了: "+product); 
             try 
              { 
                Thread.sleep(20); 
              } 
              catch(InterruptedException e) 
              { 
                e.printStackTrace(); 
              } 
          } 
        }    

    class Consumer1 implements Runnable 

        private SyncStack stack;     public Consumer1(SyncStack stack) { 
        this.stack = stack; 

        public void run() { 
          for(int i=0;i <stack.getProducts().length;i++) 
              { 
              String product =stack.pop(); 
              //System.out.println("消费了: "+product);
              try 
              { 
                Thread.sleep(1000); 
              } 
              catch(InterruptedException e) 
              { 
                e.printStackTrace(); 
              }           }      
        } 

    class SyncStack 

        private String[] products = new String[10]; 
        private int index; 
        public synchronized void push(String product) 
        { 
          if(index==product.length()) 
          { 
              try { 
                  wait(); 
              } catch (InterruptedException e) { 
                  // TODO Auto-generated catch block 
                  e.printStackTrace(); 
              } 
          } 
          notify(); 
          products[index]=product; 
          System.out.println("生产了: "+product); 
          index++; 
        } 
        
        public synchronized String pop() 
        { 
          if(index==0) 
          { 
              try { 
                  wait(); 
              } catch (InterruptedException e) { 
                  // TODO Auto-generated catch block 
                  e.printStackTrace(); 
              } 
          } 
          notify(); 
          index--; 
          String product = products[index]; 
          System.out.println("消费了: "+product); 
          return product; 
        }     public String[] getProducts() { 
          return products; 
        } 

    public class Producer_Customer { 
        
        public static void main(String[] args) { 
          SyncStack stack=new SyncStack(); 
          Producer p=new Producer(stack); 
          Consumer1 c=new Consumer1(stack);       new Thread(p).start(); 
          new Thread(c).start(); 
          } 
        } 
      

  3.   

    那就是因为打印语句是在SyncStack 外面执行啊。不知道谁不懂谁的意思了。呵呵
      

  4.   

    结贴了
    还有个疑问:class SyncStack 

        private String[] products = new String[10]; 
        private int index; 
        public synchronized void push(String product) 
        { 
          if(index==product.length()) 这个部分中的 index怎么没有初始化值啊????private int index=0; 比较好理解程序的运行
      

  5.   

    回答上面的问题:
    定义一个变量的时候,JAVA都会给它一个默认值的 
    数据类型 对应的默认值 
    byte(字节):0 
    short(短整型):0 
    int(整型):0 
    long(长整形):0L 
    folat(浮点型):0.0f 
    double(双精度):0.0b 
    char(字符型):'\u000' 
    boolean(布尔型):false 
    String(字符串型):null 但是如果你编程的时候,当定义一个数据类型和输出该数据类型写在一个main方法中就会报错 
    举例: 
    public class a7 { 
    public static void main(String[] args) { 
    int a; 
    System.out.println(a); //报错 


    但是你写在2个类里面,或者写在一个里面,给该类型用static(静态)修饰一下就不会报错 举例: 
    public class a7 { 
    static int a; //这里用静态的方法修饰 public static void main(String[] args) { 
    System.out.println(a); 
    } } 
    输出结果为 0 
      

  6.   

    public synchronized void push(String product) 
        { 
          if(index==product.length())//这里是不是写错了,应该写为:if(index==products.length)棧的下标位置应该和
          {                          //字符串数组的长度进行比较,而不是与一个字符串的长度进行比较
              try { 
                  wait(); 
              } catch (InterruptedException e) { 
                  // TODO Auto-generated catch block 
                  e.printStackTrace(); 
              } 
          } 
          notify(); 
          products[index]=product; 
          index++; 
        }