- sleep() 是 Thread 类的静态本地方法;wait() 是Object类的成员本地方法
- sleep() 方法可以在任何地方使用;wait() 方法则只能在同步方法或同步代码块中使用,否则抛出异常Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
- sleep() 会休眠当前线程指定时间,释放 CPU 资源,不释放对象锁,休眠时间到自动苏醒继续执行;wait() 方法放弃持有的对象锁,进入等待队列,当该对象被调用 notify() / notifyAll() 方法后才有机会竞争获取对象锁,进入运行状态
- JDK1.8 sleep() wait() 均需要捕获 InterruptedException 异常
测试代码:
package demo;
public class TestWaitSleep {
private static Object obj = new Object();
public static void main(String[] args) {
// 测试sleep()
// 测试 RunnableImpl1 wait(); RunnableImpl2 notify()
Thread t1 = new Thread(new RunnableImpl1(obj));
Thread t2 = new Thread(new RunnableImpl2(obj));
t1.start();
t2.start();
// 测试RunnableImpl3 wait(long timeout)方法
Thread t3 = new Thread(new RunnableImpl3(obj));
t3.start();
}
}
package demo;
public class RunnableImpl1 implements Runnable{
private Object obj;
public RunnableImpl1(Object obj) {
this.obj = obj;
}
@Override
public void run() {
System.out.println("run on RunnableImpl1");
synchronized (obj) {
System.out.println("obj to wait on RunnableImpl1");
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("obj continue to run on RunnableImpl1");
}
}
}
package demo;
public class RunnableImpl2 implements Runnable {
private Object obj;
public RunnableImpl2(Object obj) {
this.obj = obj;
}
@Override
public void run() {
System.out.println("run on RunnableImpl2");
System.out.println("睡眠3秒...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj) {
System.out.println("notify obj on RunnableImpl2");
obj.notify();
}
}
}
package demo;
public class RunnableImpl3 implements Runnable {
private Object obj;
public RunnableImpl3(Object obj) {
this.obj = obj;
}
@Override
public void run() {
System.out.println("run on RunnableImpl3");
synchronized (obj) {
System.out.println("obj to wait on RunnableImpl3");
try {
obj.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("obj continue to run on RunnableImpl3");
}
}
}
运行结果:
从上面的运行结果,能看出来执行顺序是不一样的,因为是多线程,要是执行顺序一样,那不就是单线程了嘛。
要明确sleep()方法是Thread中的,而wait()方法是Object中的。