Java中wait与sleep的区别讲解(wait有参及无参区别)

网友投稿 336 2022-08-04


Java中wait与sleep的区别讲解(wait有参及无参区别)

目录1. wait() 与wait( long timeout ) 区别2. wait(0) 与 sleep(0)区别3. wait 和sleep 释放代码4. wait 与 sleep 区别相同点:不同点:

1. wait() 与wait( long timeout ) 区别

public class WaitDemo4 {

public static void main(String[] args) {

Object lock = new Object();

Object lock2 = new Object();

new Thread(() -> {

System.out.println("线程1: 开始执行" + LocalDateTime.now());

synchronized (lock) {

try {

lock.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程1: 执行完成" + LocalDateTime.now());

}

},"无参wait线程").start();

new Thread(() -> {

System.out.println("线程2: 开始执行" + LocalDateTime.now());

synchronized (lock2) {

try {

lock2.wait(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程2: 执行完成" + LocalDateTime.now());

}

},"有参wait线程").start();

}

}

输出:

线程2: 开始执行2022-04-12T12:13:57.130

线程1: 开始执行2022-04-12T12:13:57.130

线程2: 执行完成2022-04-12T12:13:58.130

不同点:

1.wait( long timeout) :当线程超过了设置时间之后,自动恢复执行;而wait() 无线等待状态。

2. 使用无参的wait方法,线程会进入WAITING; 使用有参的wait方法,线程会进入TIMED_WAITING。

public class WaitDemo5 {

public static void main(String[] args) {

Object lock = new Object();

Object lock2 = new Object();

new Thread(() -> {

synchronized (lock2) {

System.out.println("线程2: 开始执行" + LocalDateTime.now());

try {

lock2.wait(60 * 60 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程2: 执行完成" + LocalDateTime.now());

}

},"有参wait线程").start();

new Thread(() -> {

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (lock2) {

System.out.println("唤醒线程2");

lock2.notify();

}

}).start();

}

}

输出:

线程2: 开始执行2022-04-12T12:28:23.200

唤醒线程2

线程2: 执行完成2022-04-12T12:28:24.169

public class WaitDemo6 {

public static void main(String[] args) {

Object lock = new Object();

new Thread(() -> {

System.out.println("线程1: 开始执行" + LocalDateTime.now());

synchronized (lock) {

try {

lock.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程1: 执行完成" + LocalDateTime.now());

}

},"无参wait线程").start();

new Thread(() -> {

System.out.println("线程2: 开始执行" + LocalDateTime.now());

synchronized (lock) {

try {

lock.wait(60 * 60 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程2: 执行完成" + LocalDateTime.now());

}

},"有参wait线程").start();

new Thread(() -> {

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (lock) {

System.out.println("唤醒所有线程");

lock.notifyAll();

}

}).start();

}

}

输出:

线程1: 开始执行2022-04-12T12:34:34.317

线程2: 开始执行2022-04-12T12:34:34.317

唤醒所有线程

线程2: 执行完成2022-04-12T12:34:35.295

线程1: 执行完成2022-04-12T12:34:35.295

共同点:

1. 无论是有参的wait方法还是无参的wait方法,它都可以使用当前线程进入休眠状态。

2.无论是有参的wait方法还是无参的wait方法,它都可以使用notify / ontifyAll进行唤醒。

2. wait(0) 与 sleep(0)区别

public class WaitSleepDemo7 {

public static void main(String[] args) {

Object lock = new Object();

Thread t1 = new Thread(() -> {

synchronized (lock) {

System.out.println("线程1:开始执行");

try {

lock.wait(0);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程1:执行结束");

}

},"wait(0)");

t1.start();

Thread t2 = new Thread(() -> {

System.out.println("线程2:开始执行");

try {

Thread.sleep(0);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程2:执行结束");

}, "sleep(0)");

t2.start();

}

}

输出:

线程1:开始执行

线程2:开始执行

线程2:执行结束

wait (0) : 无限期等待下去,相当于wait();

sleep(0) :相当于Thread.yeild() , 让出CPU执行权,重新调度,但是sleep(0) 会继续执行。

3. wait 和sleep 释放代码

wait 和 sleep 在有所的情况下的锁处理行为是完全不同的:

public class WaitSleepDemo8 {

public static void main(String[] args) throws InterruptedException {

Object lock = new Object();

Object lock2 = new Object();

Thread t1 = new Thread(() -> {

synchronized (lock) {

System.out.println("线程1:开始执行");

try {

lock.wait(3 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程1:结束执行");

}

cwSONTk }, "wait");

t1.start();

Thread t2 = new Thread(() -> {

synchronized (lock2) {

System.out.println("线程2:开始执行");

try {

Thread.sleep(3 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程2:结束执行");

}

}, "sleep");

t2.start();

// 创建 2 个线程,先让线程休眠 1s 之后,尝试获取,看能不能获取到锁

// 如果可以获取到锁,说明休眠时线程是释放锁的,而如果获取不到锁,说明是不释放锁

Thread t3 = new Thread(() -> {

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("尝试获取 wait 方法的锁");

synchronized (lock) {

http:// System.out.println("成功获取 wait 的锁");

}

}, "wait2");

t3.start();

Thread t4 = new Thread(() -> {

try {

TimeUnit.SECONDS.sleep(0);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("尝试获取 sleep 方法的锁");

synchronized (lock2) {

System.out.println("成功获取 sleep 的锁");

}

}, "sleep2");

t4.start();

}

}

输出:

线程1:开始执行

线程2:开始执行

尝试获取 sleep 方法的锁

尝试获取 wait 方法的锁

成功获取 wait 的锁

线程1:结束执行

线程2:结束执行

成功获取 sleep 的锁

wait方法(不管是有参还是无参)在执行的时候都会释放锁;而sleep 方法不会释放锁。

4. wait 与 sleep 区别

相同点:

1. 都是可以让线程进入休眠

2. 都可以响应Interrupt(中断)请求

不同点:

1. wait必须配合synchronized一起使用;而sleep不需要。

2. wait 属于Object(对象)的方法;而sleep属于Thread(线程)的方法。

3. sleep 不释放锁;而wait释放锁。

4. sleep 必须要传递一个数值类型的参数;而wait可以不传参。

5. sleep 让线程进入到TIMED_WAITING状态;而无参的wait方法让线程进入了WAITING状态。

6. 一般情况下,sleep只能等待超时时间之后再回复执行;而wait可以接受notify / notifiAll之后就绪执行。

(MS):

1.为什么 wait 释放锁⽽ sleep 不释放锁?

【JVM 强制语法检查,wait ⽅法默认等待⽆期限】

2.为什么 wait 要放在 Object 中?

【wait 使⽤要加锁,也就是要操作锁,锁是针对对象级别的⽽⾮线程级别的,线程和对象是⼀对多,所以 wait 最便利的⽅式是放在 Object 中】


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java防止频繁请求、重复提交的操作代码(后端防抖操作)
下一篇:Java实战之课程在线学习系统的实现(JAVA网课)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~