1、sleep是Thread类的方法,wait是Object类的方法
2、sleep不需要唤醒,wait需要唤醒
3、sleep不会释放对象锁,wait会释放对象锁
4、sleep不依赖monitor对象,而wait依赖monitor对象
我觉得第1、2项没什么需要额外解释的了,我们通过代码验证一下第3、4项吧
sleep不会释放对象锁,wait会释放对象锁
1.sleep()
package com.thread.demo;
/**
* @Author: Peacock__
* @Date: 2019/4/29 18:02
*/
public class SleepDemo extends Thread{
private final static Object LOCK= new Object();
public SleepDemo(String name) {
super(name);
}
@Override
public void run() {
synchronized (LOCK){
try {
System.out.println(Thread.currentThread().getName()+" Enter...");
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.thread.demo;
/**
* @Author: Peacock__
* @Date: 2019/4/29 18:00
*/
public class DifferenceOfSleepAndWait {
public static void main(String[] args) {
Thread demo1 = new SleepDemo("A");
Thread demo2 = new SleepDemo("B");
demo1.start();
demo2.start();
}
}
测试结果:控制台先输出“A Enter...”,10秒后输出“B Enter...”,程序退出。
2.wait()
package com.thread.demo;
/**
* @Author: Peacock__
* @Date: 2019/4/29 18:02
*/
public class WaitDemo extends Thread{
private final static Object LOCK= new Object();
public WaitDemo(String name) {
super(name);
}
@Override
public void run() {
synchronized (LOCK){
try {
System.out.println(Thread.currentThread().getName()+" Enter...");
LOCK.wait(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.thread.demo;
/**
* @Author: Peacock__
* @Date: 2019/4/29 18:00
*/
public class DifferenceOfSleepAndWait {
public static void main(String[] args) {
Thread demo1 = new WaitDemo("A");
Thread demo2 = new WaitDemo("B");
demo1.start();
demo2.start();
}
}
测试结果:控制台几乎同时输出“A Enter... B Enter...”,大约10秒后程序退出。
sleep不依赖monitor对象,而wait依赖monitor对象
1.sleep()
package com.thread.demo;
/**
* @Author: Peacock__
* @Date: 2019/4/29 18:00
*/
public class DifferenceOfSleepAndWait {
public static void main(String[] args) throws InterruptedException {
Thread.sleep(1000);
}
}
可以正常运行,1秒后程序退出。
2.wait()
package com.thread.demo;
/**
* @Author: Peacock__
* @Date: 2019/4/29 18:00
*/
public class DifferenceOfSleepAndWait {
public static void main(String[] args) throws InterruptedException {
final Object o = new Object();
o.wait(1000);
}
}
运行发现抛出了IllegalMonitorStateException异常
之前synchronized关键字实现原理博文中描述了线程获取对象锁时与对象的ObjectMonitor密切相关,通过JDK8文档中如图描述,也就是说在执行某对象的wait的时候,必须持有此对象的对象锁,如果wait方法在synchronized代码中执行,该线程很显然已经持有了此对象的锁。
想深究为什么wait要在synchronized里调用请参考:JVM源码分析之Object.wait/notify实现
那我们放到synchronized代码块中 执行一下:
package com.thread.demo;
/**
* @Author: Peacock__
* @Date: 2019/4/29 18:00
*/
public class DifferenceOfSleepAndWait {
public static void main(String[] args) throws InterruptedException {
final Object o = new Object();
synchronized (o){
o.wait(1000);
}
}
}
将wait()放入同步代码块中可以正常运行,1秒后程序退出。