相关文章:
这里我们再来了解下 sleep() 方法和 wait() 方法的区别
一、举例说明
public class WaitSleepDemo {
public static void main(String[] args) {
final Object lock = new Object();
new Thread(() -> {
System.out.println("thread A is waiting to get lock");
synchronized (lock) {
try {
System.out.println("thread A get lock");
Thread.sleep(20);
System.out.println("thread A do wait method");
lock.wait(1000);
System.out.println("thread A is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
System.out.println("thread B is waiting to get lock");
synchronized (lock) {
try {
System.out.println("thread B get lock");
System.out.println("thread B is sleeping 10 ms");
Thread.sleep(10);
System.out.println("thread B is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
// thread A is waiting to get lock
// thread A get lock
// thread B is waiting to get lock
// thread A do wait method
// thread B get lock
// thread B is sleeping 10 ms
// thread B is done
// thread A is done
-
如上所示,我们 new 了两个线程 A 和 B,线程 A 与线程 B 之间有 10 ms 的延迟
-
由输出结果可知,线程 A 先开始执行,获得了 lock 锁,接着调用了 sleep() 方法休眠 20 ms
-
在主线程 10 ms 的延迟过后,线程 B 也开始执行,当线程 B 执行到同步代码块时,需要获取到 lock 锁,由于此时 lock 锁由线程 A 持有且没有释放,因此线程 B 进入了阻塞状态
-
当线程 A 休眠完 20 ms 后又继续执行,接着又调用了 wait() 方法休眠 1000 ms,此时 lock 锁被释放
-
与此同时,线程 B 获取到了 lock 锁后继续执行直到执行完毕
-
最后线程 A 休眠 1000 ms 后自动被系统唤醒,重新获得了 lock 锁,继续执行直到执行完毕 (如果线程 A 被唤醒后,线程 B 还未释放 lock 锁,则线程 A 也会进入阻塞状态)
-
因此我们可以知道,sleep() 方法会使线程进入阻塞状态,但不会释放已持有的锁标记;而 wait() 方法同样会使线程进入阻塞状态,但会释放已持有的锁标记
二、归纳总结
-
所在类不同
-
sleep() 是 Thread 类的方法
-
wait() 是 Object 类的方法
-
-
使用场景不同
-
sleep() 方法可以在任何地方使用
-
wait() 方法只能在 synchronized 修饰的方法或代码块中使用
-
-
调用方法后,对锁标记的操作不同
-
调用 sleep() 方法,线程会进入阻塞状态,但不会释放已持有的锁标记
-
调用 wait() 方法,线程也会进入阻塞状态,但会释放已持有的锁标记,让其他正在等待该资源的线程获取到锁标记,进而去运行
-