import java.util.ArrayList;
import java.util.List;
public 
class WaitNotify extends Thread {
    
	private String flag="false";
	
	private List<String> list=new ArrayList<String>();
	
	public static void main(String[] args) { 
      
    	WaitNotify t = new WaitNotify(); 
    	
    	//正确的用法,wait跟notify的用法肯定是在不同的2个
线程里面,而且wait跟notify必须监控同一个句柄或者指针自身不变的资源
    	//notify线程一定不能一直占着锁
    	RightWaitThread rw =t.new RightWaitThread();
    	rw.start();
    	
    	RightNotifyThread pd =t.new RightNotifyThread();
    	pd.start();
    	
    	
    	//以下是没有
意义(监控的没有意义) 的用法
    	/*NomanningWaitThread wt =t.new NomanningWaitThread();
    	wt.start();
    	
    	NomanningNotifyThread nt =t.new NomanningNotifyThread();
    	nt.start();*/
    	/*
    	//以下是
错误 的用法,监控了一个变化的对象
    	ChangeWaitThread ct =t.new ChangeWaitThread();
    	ct.start();
    	
    	ChangeNotifyThread cn =t.new ChangeNotifyThread();
    	cn.start();
    	
    	//以下是错误 的用法,这个线程完全阻塞了,所以不能走下去,notify那里根本走不到,换句话说不管怎么用nofity块一定要能运行到
    	
    	
        t.waitThis();
        System.out.println("running here...");
        t.start();//t线程开始执行
        t.notifiyThis();*/
  
    }   
     
     //生产消费 
    class RightWaitThread extends Thread
    {
    	 public void run() {
    		 synchronized (list) {
				try {
					while(true)
					{
						Thread.sleep(1000);
						System.out.println("while consume RightWaitThread ...");
						if(list.isEmpty())
						{	
							list.wait();
							String e=list.get(0);
							list.remove(0);
							System.out.println("consume element:"+e+"   list size:"+list.size());
						}			
					}
					 
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}    		 
    	 }    	 
    }
    
    class RightNotifyThread extends Thread
    {
    	 public void run() {
    		 try {
	    			 while(true)
	    			 {
	    				 Thread.sleep(5000);
						 doWork();
	    			 }   			     				 				 				
				}				
				
			catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	 }    
    	 public void doWork() {
			 synchronized (list) {
				// while(true) //这里notify一定不能一直占着锁,应该有外部生产者觉得要做的作业,这里应该是一个独立的作业
				 //{
					 System.out.println("while produce RightNotifyThread ...");
					 list.add("hello");
       				 list.notify();	
				// }    					     				 				 				
			}		
	 }    	 
    }
    
    //有问题的用法,nontify被阻塞了
    private void waitThis()
    {
    	synchronized (this) {
            try {
                System.out.println("waitThis wait for t to complete...");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("total:" + this.total);
        }
    }
    
    private void notifiyThis()
    {
    	synchronized (this) {            
                System.out.println("notifiyThis notifiy all...");
                this.notify();            
        }
    }
    int total;
    public void run() {
        synchronized (this) {//运行期间保持锁
        	System.out.println("in");
            for (int i = 0; i < 100; i++) {
                total += i;
            }
            System.out.println(total);
            this.notify();//唤醒等待此对象锁的一个线程
        }
    }
    
    // 这个用法是没有问题的,因为没有监控对象没有比那话,但是没有意义
     
    class NomanningWaitThread extends Thread
    {
    	 public void run() {
    		 synchronized (flag) {
				try {
					 System.out.println("begin NomanningWaitThread wait for t to complete...");
					 flag.wait();
					 System.out.println("after NomanningWaitThread wait for t to complete...");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
    		 
    	 }
    	 
    }
    
    class NomanningNotifyThread extends Thread
    {
    	 public void run() {
    		 try {
    			 synchronized (flag) {
    				 Thread.sleep(5000);
    				  System.out.println("NomanningNotifyThread notify...");
    				 flag.notify();					
				}				
				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	 }    	 
    }
    
     //这个用法是没有问题的,因为没有监控对象没有比那话,但是没有意义    
    class ChangeWaitThread extends Thread
    {
    	 public void run() {
    		 synchronized (flag) {
				try {
					while(true)
					{
							System.out.println("begin ChangeWaitThread wait for t to complete...");
							 flag.wait();
							 System.out.println("after ChangeWaitThread wait for t to complete...");	
					}					 
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}    		 
    	 }    	 
    }
    
    
     // 这个用法是没有问题的,因为没有监控对象没有比那话,但是没有意义    
    class ChangeNotifyThread extends Thread
    {
    	 public void run() {
    		 try {
    			 synchronized (flag) {
    				 while(true)    					 
    				 {
    					 flag="true";
    					 Thread.sleep(5000);
	       				 System.out.println("ChangeNotifyThread notify...");
	       				 flag.notify();	
    				 }    				 				
				}				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	 }   	 
    }
}
查看kill -3线程
堆栈,可以看到监视的是同一个对象
Full 
thread dump Java HotSpot(TM) 64-Bit Server VM (1.5.0_22-b03 mixed mode):
"DestroyJavaVM" prio=1 tid=0x00000000401157e0 nid=0x3285 waiting on condition [0x0000000000000000..0x00007fffce241c70]
"Thread-2" prio=1 tid=0x00002aaaaacd0190 nid=0x3298 waiting on condition [0x0000000041463000..0x0000000041463b20]
	at java.lang.Thread.sleep(Native Method)
	at WaitNotify$RightNotifyThread.run(WaitNotify.java:82)
	- locked <
0x00002ade13e531b8> (a java.util.ArrayList)
"Thread-1" prio=1 tid=0x00002aaaaaccf0f0 nid=0x3297 in Object.wait() [0x0000000041362000..0x0000000041362ca0]
	at java.lang.Object.wait(Native Method)
	- waiting on <
0x00002ade13e531b8> (a java.util.ArrayList)
	at java.lang.Object.wait(Object.java:474)
	at WaitNotify$RightWaitThread.run(WaitNotify.java:60)
	- locked <
0x00002ade13e531b8> (a java.util.ArrayList)