当前位置:网站首页>线程的 sleep() 方法与 wait() 方法的区别
线程的 sleep() 方法与 wait() 方法的区别
2022-06-24 09:43:00 【文丑颜不良啊】
总的来说,线程的 sleep() 方法和 wait() 方法有以下几点区别:
(1)sleep() 方法是 Thread 类中的方法,而 wait() 方法是 Object 类中的方法。
(2)sleep() 方法不会释放 lock,但是 wait() 方法会释放,而且会加入到等待队列中。
(3)sleep() 方法不依赖于同步器 synchronized(),但是 wait() 方法 需要依赖 synchronized 关键字。
(4)线程调用 sleep() 之后不需要被唤醒(休眠时开始阻塞,线程的监控状态依然保持着,当指定的休眠时间到了就会自动恢复运行状态),但是 wait() 方法需要被重新唤醒(不指定时间需要被别人中断)。
public class SleepDemo {
public static final Object LOCK = new Object();
public static void main(String[] args) {
Stream.of("线程1", "线程2").forEach(a -> new Thread(a) {
@Override
public void run() {
new SleepDemo().testSleep();
}
}.start());
}
private void testSleep() {
synchronized (LOCK) {
try {
System.out.println(Thread.currentThread().getName() + "正在执行: " + System.currentTimeMillis() / 1000);
// 休眠 2 s
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
} catch (Exception e) {
}
}
}
}
可以看到,线程 1 先抢到了资源,执行主体方法时要求睡眠 2 秒,那么在这两秒时间内,即使线程 1 没有任何动作,线程 2 也不能抢占资源。 需要注意的是,在调用 sleep() 方法时,如果有两个线程,那么要想实现线程睡眠的效果就需要使用 synchronized() 方法,否则达不到效果。
public class SleepDemo {
// public static final Object LOCK = new Object();
public static void main(String[] args) {
Stream.of("线程1", "线程2").forEach(a -> new Thread(a) {
@Override
public void run() {
new SleepDemo().testSleep();
}
}.start());
}
private void testSleep() {
// synchronized (LOCK) {
try {
System.out.println(Thread.currentThread().getName() + "正在执行: " + System.currentTimeMillis() / 1000);
// 休眠 2 s
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
} catch (Exception e) {
System.out.println(e);
}
// }
}
}

如上所示,不使用 synchronized() 的话就会出现两个线程同时执行,同时睡眠,又同时恢复执行。
由此可知,调用 sleep() 方法时,并不是强依赖于 synchronized() 方法,如果我只有一个线程,那么使用 synchronized() 方法和不使用 synchronized() 方法的效果是一样的。如果有两个线程的话,也可以选择使用或者不使用 synchronized() 方法。但是 wait() 方法就不一样了,wait() 方法强依赖于 synchronized() 方法,如果不使用 synchronized() 方法的话,wait() 方法的程序就会报错。
public class WaitDemo {
public static final Object LOCK = new Object();
public static void main(String[] args) {
Stream.of("线程1", "线程2").forEach(a -> new Thread(a) {
@Override
public void run() {
WaitDemo.testWait();
}
}.start());
}
private static void testWait() {
// synchronized (LOCK) {
try {
System.out.println(Thread.currentThread().getName() + "正在执行: " + System.currentTimeMillis() / 1000);
// 等待 2 s
LOCK.wait(2000);
System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
} catch (InterruptedException e) {
System.out.println(e);
}
}
// }
}

使用 synchronized 关键字修饰后:
public class WaitDemo {
public static final Object LOCK = new Object();
public static void main(String[] args) {
Stream.of("线程1", "线程2").forEach(a -> new Thread(a) {
@Override
public void run() {
WaitDemo.testWait();
}
}.start());
}
private static void testWait() {
synchronized (LOCK) {
try {
System.out.println(Thread.currentThread().getName() + "正在执行: " + System.currentTimeMillis() / 1000);
// 等待 2 s
LOCK.wait(2000);
System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
因为在代码中有指定 wait(2000),所以当 2 秒之后该线程就会恢复执行的,而不用另外一个线程去唤醒,如果 wait() 方法没有指定时间的话,那么该线程就会一直等待~
除此之外,一个线程一旦被 wait 之后,就必须有另外一个线程去唤醒,否则一直处于等待状态。
public class WaitDemo {
public static final Object LOCK = new Object();
private void testWait1() {
synchronized (LOCK) {
try {
System.out.println(Thread.currentThread().getName() + "开始执行: " + System.currentTimeMillis() / 1000);
LOCK.wait();
System.out.println(Thread.currentThread().getName() + "恢复执行: " + System.currentTimeMillis() / 1000);
} catch (Exception e) {
System.out.println(e);
}
}
}
private void testNotify() {
synchronized (LOCK) {
try {
Thread.sleep(2000);
LOCK.notify();
System.out.println(Thread.currentThread().getName() + "唤醒另一线程: " + System.currentTimeMillis() / 1000);
} catch (Exception e) {
System.out.println(e);
}
}
}
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
new WaitDemo().testWait1();
}
}.start();
new Thread() {
@Override
public void run() {
new WaitDemo().testNotify();
}
}.start();
}
}
边栏推荐
- Binary tree part I
- 413-二叉树基础
- Can the long-term financial products you buy be shortened?
- Regular matching mobile number
- Geogebra instance clock
- El table Click to add row style
- Why is JSX syntax so popular?
- SQL Server AVG function rounding
- Indexeddb local storage, homepage optimization
- The great charm of cookies
猜你喜欢

SSH Remote Password free login

Operator details

TP5 using post to receive array data times variable type error: solution to array error

How large and medium-sized enterprises build their own monitoring system

js单例模式

uniapp 开发微信公众号,下拉框默认选中列表第一个

How does home office manage the data center network infrastructure?

p5.js实现的炫酷交互式动画js特效

Phpstrom code formatting settings

Juul, the American e-cigarette giant, suffered a disaster, and all products were forced off the shelves
随机推荐
观察者模式
Which of the top ten securities companies has the lowest Commission and is the safest and most reliable? Do you know anything
Geogebra instance clock
Machine learning perceptron and k-nearest neighbor
MySQL data advanced
Cicflowmeter source code analysis and modification to meet requirements
port 22: Connection refused
正规方程、、、
Network of test and development - Common Service Protocols
2021-08-17
numpy.logical_and()
4.分类管理业务开发
引擎国产化适配&重构笔记
web网站开发,图片懒加载
二叉树第一部分
Observer mode
SSH Remote Password free login
PHP encapsulates a file upload class (supports single file and multiple file uploads)
TP5 using post to receive array data times variable type error: solution to array error
Go language development environment setup +goland configuration under the latest Windows