1.首先 sleep 方法是Thread类中的静态方法,他的作用是使当前线程暂时睡眠指定的时间,可以不用放在synchronized方法或者代码块中,但是 wait 方法是Object类的方法,它是使当前线程暂时放弃监视对象的使用权进行等待,必须要放在synchronized方法或者代码块中

2.调用线程的sleep 方法当前线程会让出CPU给其他线程执行,但不会释放锁,依然占用锁的使用权,但是 wait方法会释放锁。

3.sleep方法到睡眠指定时间后会自动回复到可运行状态,但是wait方法需要另外一个拥有锁的对象调用 notify 方法进行唤醒,否则将一直挂起。

验证代码如下:

 package test.main.com;

 public class SleepAndWait {

     private static class Thread1 implements Runnable{
@Override
public void run() {
synchronized (SleepAndWait.class) {
System.out.println("thread 1 enter run method...");
System.out.println("thread 1 start waiting...");
try {
SleepAndWait.class.wait();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("thread 1 ending waiting...");
System.out.println("thread 1 is over...");
}
}
} private static class Thread2 implements Runnable{ @Override
public void run() {
synchronized (SleepAndWait.class) {
System.out.println("thread 2 enter run method...");
System.out.println("thread 2 sleeping...");
SleepAndWait.class.notifyAll(); try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("thread2 is going on....");
System.out.println("thread2 is over!!!");
}
} } public static void main(String[] args) {
new Thread(new Thread1()).start();
new Thread(new Thread1()).start();
new Thread(new Thread1()).start(); try {
System.out.println("main Thread begin sleeping....");
Thread.sleep(8000);
System.out.println("main Thread end sleeping....");
} catch (InterruptedException e) {
e.printStackTrace();
} new Thread(new Thread2()).start();
} }

说明:虽然Thread2调用了notify,但是由于Thread2调用的是sleep,所以Thread2实际上还是没有释放锁,因此Thread1的Run方法一直拿不到锁,只有等待Thread2执行完毕以后,Thread1拿到锁,然后才能继续执行。