欢迎访问宙启技术站
智能推送

Java中wait和sleep有什么区别

发布时间:2023-05-16 04:59:56

Java中wait和sleep都是线程的方法,这两个方法都涉及到线程状态的变化,并且可以控制线程的等待和唤醒。不过,wait和sleep是不同的方法,它们有着不同的用途和自身的特点。

一、wait

1.1 定义

wait是Object类的方法,它的作用是让线程等待某个条件满足时(或者是其他线程所通知)进入等待状态暂停执行。

1.2 使用

wait方法必须要在synchronized代码块中调用。当线程调用wait方法后,JVM会将该线程挂起,放入等待队列中,同时释放锁标记。

wait方法有以下三种重载形式:

//等待无限时间
public final native void wait() throws InterruptedException;
//等待指定时间
public final native void wait(long timeout) throws InterruptedException;
//等待指定时间并指定毫秒数
public final void wait(long timeout, int nanos) throws InterruptedException;

当线程处于等待状态时,它可以通过notify()和notifyAll()方法唤醒。这些方法也必须在synchronized代码块中调用。notify()方法会唤醒等待队列中任意一个线程,而notifyAll()方法会唤醒等待队列中所有的线程。

1.3 特点

wait方法的特点如下:

a. wait()方法将会让当前线程永久地等待下去,直到其它线程在同一个对象上执行notify()方法或notifyAll()方法,并且在获得了对象的锁后才能继续执行。

b. wait(long timeout)方法则使当前线程等待指定的毫秒数,如果在指定时间内没有被notify()唤醒,该线程会自动唤醒并且重新竞争锁,如果竞争到锁,线程就可以继续执行,否则继续在等待状态。

c. 被唤醒的线程不会立刻执行,它会需要和其他等待该同步资源的线程一起竞争锁,锁竞争成功后,才会继续执行线程。

二、sleep

2.1 定义

sleep是Thread类的静态方法,它的作用是让当前线程暂停指定的时间,进入休眠状态,但不会释放锁标记。

2.2 使用

sleep方法的使用非常简单,只需要在代码中调用即可。

sleep方法有以下两种重载形式:

//睡眠指定的时间
public static native void sleep(long millis) throws InterruptedException;
//睡眠指定的时间和毫秒数
public static void sleep(long millis, int nanos) throws InterruptedException;

2.3 特点

sleep方法的特点如下:

a. sleep()方法暂停线程的时间是固定的,并且不会受到通知的唤醒。

b. 调用sleep方法时,线程不会释放锁标记,也就是说,其他线程无法在该线程睡眠时进入同步方法,但是该线程睡眠结束后,仍需要争夺锁,才能继续执行。

三、区别与联系

从上述介绍可以看出,wait方法和sleep方法的基本作用都是让线程等待,但是它们的使用场景和具体实现都有所不同。

wait方法主要是针对线程之间的协作,当一个线程需要等待另一个线程完成某个处理之后再继续执行时,就可以使用wait方法。wait方法必须在同步代码块中调用,而且还需要和notify或notifyAll一起使用,这两个方法都需要在同步代码块中调用。另外,wait方法会释放锁标记,让其他线程有机会进入同步代码块。值得注意的是,wait方法只能在持有对象锁时调用。

而sleep方法则主要是针对时间的控制,当一个线程需要等待一个指定的时间,或者是等待某个资源被操作之后再继续执行时,就可以使用sleep方法。sleep方法可以在任何地方调用,因为它不需要在同步代码块内使用,同时也不需要和notify或notifyAll一起使用。另外,sleep方法并不会释放锁标记,因此其他线程无法进入同步代码块。

总之,wait方法和sleep方法只是类似的过程,但它们的本质和实现都是不一样的,所以在不同的场景下使用不同的方法也很有必要。通过对wait方法和sleep方法的理解,我们可以更好地掌握Java多线程的编程技巧,进而写出更加高效的代码。