概述
wait和sleep的区别,这个确实是面试中非常常见的一道题目,这里我们通过源码并结合示例来一起加深下对wait和sleep的理解 。
主要有4点不同
- sleep是Thread的方法,wait是Object的方法
- sleep不会释放锁(Monitor), wait会让当前线程释放锁
- sleep 不依赖 Monitor,但是wait需要依赖Monitor
- sleep方法不需要被唤醒,wait需要唤醒 (wait(long millons) 方法除外)
接下来我们分别来看下这4点区别
区别
sleep是Thread的方法,wait是Object的方法
直接看下源码即可
Object#wait
Thread#sleep
sleep不会释放锁(Monitor), wait会让当前线程释放锁
sleep不会释放锁(Monitor) 举个例子
代码语言:javascript复制package com.artisan.test;
import java.util.Date;
import java.util.stream.Stream;
public class SleepAndWaitDiffDemo {
private final static Object LOCK = new Object();
private static void method1() {
synchronized (LOCK){
System.out.println(Thread.currentThread().getName() " -- " new Date());
try {
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// 开启两个线程
Stream.of("T1","T2").forEach(threadName -> {
new Thread(threadName){
@Override
public void run() {
super.run();
// 调用methood1
method1();
}
}.start();
});
}
}
输出
wait会让当前线程释放锁
代码语言:javascript复制package com.artisan.test;
import java.util.Date;
import java.util.stream.Stream;
public class SleepAndWaitDiffDemo {
private final static Object LOCK = new Object();
private static void method2() {
synchronized (LOCK){
System.out.println(Thread.currentThread().getName() " -- " new Date());
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// 开启两个线程
Stream.of("T1","T2").forEach(threadName -> {
new Thread(threadName){
@Override
public void run() {
super.run();
// 调用methood2
method2();
}
}.start();
});
}
}
sleep 不依赖 Monitor,但是wait需要依赖Monitor
代码语言:javascript复制package com.artisan.test;
public class SleepAndWaitDiffDemo {
private final static Object LOCK = new Object();
private static void method1() {
try {
Thread.sleep(2_000);
System.out.println("method1休眠2秒结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void method2() {
try {
// 不加synchronized关键字,会抛出IllegalMonitorStateExceptio
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
method1();
method2();
}
}
运行结果
如何改呢?
代码语言:javascript复制private static void method2() {
synchronized (LOCK){
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized (LOCK),然后 LOCK.wait即可 。
sleep方法不需要被唤醒,wait需要唤醒 (wait(long millons) 方法除外)
从 sleep不会释放锁(Monitor), wait会让当前线程释放锁 这个例子中,我们可以看到sleep方法执行后,整个主线程就退出了,但 wait方法的,T1 和 T2 都处于waiting状态了,需要被唤醒才能继续执行…