sleep是让线程暂停指定的时间,wait是让线程等待,知道有notify方法出现在继续运行,sleep不释放对象锁,wait释放对象锁。这在很多地方都有写到,但没有例子不好理解

 

 
  
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3.  
  4.  
  5. public class thread {  
  6.     public List list=new ArrayList();  
  7.     Integer i=0;//新建一个对象,随便什么,就为了借用它的锁而已。  
  8.     public static void main(String[] args){  
  9.         thread th=new thread();  
  10.         A a=th.new A();  
  11.         B b=th.new B();  
  12.         Thread add=new Thread(a);  
  13.         Thread get=new Thread(b);  
  14.         add.start();  
  15.         get.start();  
  16.           
  17.     }  
  18.     class A extends Thread{  
  19.         public void run(){  
  20.             synchronized(i){  
  21.                 try {  
  22.                     //Thread.sleep(1000);  
  23.                     i.wait();//这里调用了对象i的wait方法,那么就表示所在线程暂时放弃i的对象锁,并阻塞在这里,同时把机会让给同样使用i锁的B线程执行  
  24.                 } catch (InterruptedException e) {  
  25.                     // TODO Auto-generated catch block  
  26.                     e.printStackTrace();  
  27.                 }  
  28.                 for(int j=0;j<list.size();j++){  
  29.                     System.out.print(list.get(j));  
  30.                 }  
  31.             }  
  32.               
  33.         }  
  34.     }  
  35.     class B extends Thread{  
  36.         public void run(){  
  37.             synchronized(i){  
  38.                 for(int j=0;j<10;j++){  
  39.                     list.add(j);  
  40.                 }  
  41.                 i.notify();//这里调用了i的notify方法,表示B线程用完i锁了,现在可以归还了,此时A线程就会在得到锁,并继续执行。  
  42.             }  
  43.         }  
  44.     }  

从如上代码中可见,线程B是负责向集合中加值的,线程A是负责从集合中取值的,如果不进行同步处理,那么如果两个线程同时运行,那么A可能在B加入值之前就从集合中取值,那么就会报错,所以必须进行同步代码的操作(也可以加入flag来判断是否到了A中从集合里取值的时机)。

而用sleep就没有上面的功能了,因为从代码中可以发现,不管是A线程先抢到cpu开始执行还是B线程先执行,他们中的一个肯定会拿到i的锁的,但拿到后i的锁就没有使用wait方法释放过,那假设B先拿到锁了,向list中加入值完成了,那也别指望A能打印出来,因为A一直阻塞在(i){

这个位置,一直在等待i的对象锁。没有锁就不会向下执行。

synchronized