请看如下两段线程的代码:
public class Producer extends Thread {
private ProductList products = ProductList.getInstance();
public void run() {
         synchronized (products)
         { 
    System.out.println("生产者");   
            products.notify();    //此处设置断点 B处
          }
        }
}public class Consumer extends Thread {
private ProductList products = ProductList.getInstance();
public void run() {
         synchronized (products)
         { 
    System.out.println("消费者");  
            products.wait(); // A处
            System.out.println("消费者已完成!");  
          }
        }
}
products是同一个实例,同时运行这两个线程,第一段程序通过设置断点停在B处。第二段程序通过wait停在A处。此时程序已经输出如下:
消费者
生产者不能理解:通过synchronized关键字对products进行互斥 第二段程序还没有输出“消费者已完成”,也就是说还没跳出synchronized代码块,那为什么第一段程序就能够输出“生产者”(也就是能够进入第一段程序的synchronized代码块)呢?不是已经对products这个对象加锁还没退出么?描述清楚了吧 谢谢回答!!

解决方案 »

  1.   

    wait方法:
            该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所在的代码块的锁,并在其他线程调用notify或者notifyAll方法时恢复到竞争锁状态(一旦获得锁就恢复执行)。我觉得这段话很好的解释了 。
    如果你把 
    System.out.println( "消费者 ");    
                            products.wait();   //   A处 替换成
    System.out.println( "消费者 ");    
                            Thread.sleep(100000);   //   A处 
     = = 。。就能看到效果了。。当然必须让Consumer   线程先启动
      

  2.   

    wait方法导致当前线程将其自身放置在对象的等待集中,然后放弃此对象上的所有同步要求。由于 wait 方法将当前的线程放入了对象的等待集中,所以它只能解除此对象的锁定。