import java.util.LinkedList;
public class Syn{
    private LinkedList<Object> myList =new LinkedList<Object>();
    private int MAX = 10;
    public Syn(){}
    public void start(){
    new Producer().start();
    new Consumer().start();
    }
    public static void main(String[] args){
    Syn s1 = new Syn();
    s1.start();
    }
    class Producer extends Thread{        
     public void run(){
     for(int i=0;i<50;i++){
     try{
                 sleep(10);
                }catch(Exception e){
                 e.getMessage();
                }
     synchronized(myList){
         try{
             while(myList.size() == MAX){  //用while循环,不用if()
                    System.out.println("warning: it's full!");
                    myList.wait();
                }
                Object o = new Object();
                if(myList.add(o)){
                    System.out.println("Producer: " + o);
                    myList.notify();
                }
            }catch(InterruptedException e){
                System.out.println("producer is interrupted!");
            }
        }
    }
        }
    }
    class Consumer extends Thread{
        public void run(){
         for(int i=0;i<50;i++){
     try{
                 sleep(100);
                }catch(Exception e){
                 e.getMessage();
                }
        synchronized(myList){
            try{
                while(myList.size() == 0){  ////用while循环,不用if()
                    System.out.println("warning: it's empty!");
                    myList.wait();
                }
                Object o = myList.removeLast();
                System.out.println("Consumer: " + o);
                myList.notify();
            }catch(InterruptedException ie){
                System.out.println("consumer is interrupted!");
            }
        }
    }
        }
    }
}
//rt,多线程的生产者消费者模式,一个生产者和一个消费者,帮解释下为何不用if,要用while(),没弄明白。

解决方案 »

  1.   

    myList.wait();的情况下,可以用if
      

  2.   

    你无法保证你的一次wait()过后Consumer/Producer操作已经完成举个例子:如果你在Consumer中遇到货物为空,需要wait,如果你wait结束后Producer的生产操作仍然没有完成,而你又用了if,那么你就将在货物为空的情况下执行消费动作,显然这是有问题的。而用while的话则保证在货物为空时不会跳出循环,避免了这个问题
      

  3.   

    无法保证一次wait后list中就不满了或不空了,所以while
      

  4.   


    while(myList.size() == 0){  ////用while循环,不用if()
                                System.out.println("warning: it's empty!");
                                myList.wait();
                            }
     和while(true){  ////用while循环,不用if()
    if(myList.size() == 0){
      System.out.println("warning: it's empty!");
                                myList.wait();}
                                                      }
    有什么区别?
      

  5.   

    没有完全理解啊,Producer的生产操作没有完成的话,怎么在货物为空的情况下执行消费动作啊?不是要等Producer的生产操作完成,唤醒Consumer并退出同步块,释放对象锁之后才有可能继续消费吗?为什么不能保证?悟性太低,sorry啊...
      

  6.   

    为什么不能保证一次wait后list中就不满了或不空了?帮忙解释下,谢谢啊
      

  7.   

    因为多线程
    多用户
    比如说,某个用户第一次得到锁时list为空,他wait,下次被唤醒时,list可能还是空的。因为有肯能其他用户购买了产品清空了表。如果用if他将不再判断list是否为空,直接继续,引起错误
    但如果用while则每次被唤醒时都先检查list是否为空再继续生产基本是一个道理
      

  8.   

    不过之前没看到你下面一行写一个生产者一个消费者,如果是这样,用if应该也没有太大问题,如果没有其他线程加同一个锁的话
    不过用while更符合逻辑,才是纯粹的线程安全
      

  9.   

    wait()即为wait(0),并不是一直等到Producer/Consumer执行完才唤醒,而是wait一个很短的固定的时间就被唤醒,你不能保证在这段时间内Producer/Consumer已经执行完
      

  10.   


    当然有区别  if只有一次 while可以不止一次 
     myList.wait();这里wait后,线程等在这里
    等到别个线程nofity后
    继续执行,这时是有必要再判断myList.size()的大小的
    简单地,满了的水桶不能再装水进去了 
      

  11.   

    这里用while而不用if是因为while可以当myList.size() == MAX为真的时候实现无限循环,这样子既能是这个线程进入等待队列又能释放自己的锁标记,从而使consumer线程执行;
    第二个使用while也是等到linckenlist为空的时候无限循环打印"warning: it's empty!而if不能实现循环。
      

  12.   

    while可以防止if那样不检查条件继续向下执行代码了
      

  13.   

    线程一般多用while(){},因为多线程具有不确定性,用if(){}可能在条件未完全满足的情况继续往下执行了,造成了错误。