线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
当前回答
等待和睡眠的方法非常不同:
睡眠无法“唤醒”, 而wait在等待期间有一种“唤醒”的方式,由另一个线程调用notify或notifyAll。
仔细想想,这些名字在这方面令人困惑;然而,sleep是一个标准名称,而wait就像Win API中的WaitForSingleObject或WaitForMultipleObjects。
其他回答
一个尚未提及的关键区别是:
sleep()不会释放它在线程上持有的锁, 同步(锁){ thread . sleep (1000);// LOCK被持有 } Wait()释放它在对象上持有的锁。 同步(锁){ LOCK.wait ();// LOCK不被持有 }
Sleep()方法导致当前线程在指定的时间内从运行状态转移到阻塞状态。如果当前线程拥有任何对象的锁,那么它会一直持有它,这意味着其他线程不能在该类对象中执行任何同步方法。
Wait()方法会导致当前线程在指定的时间内进入阻塞状态或直到notify,但在这种情况下,线程会释放对象的锁(这意味着其他线程可以执行调用对象的任何同步方法)。
这里有很多答案,但我找不到任何一个提到的语义区别。
这与线程本身无关;这两种方法都是必需的,因为它们支持非常不同的用例。
sleep()让线程像以前一样进入睡眠状态,它只是打包上下文并在预定义的时间内停止执行。因此,为了在到期时间之前唤醒它,您需要知道Thread引用。这在多线程环境中并不常见。它主要用于时间同步(例如,在3.5秒内醒来)和/或硬编码的公平性(只睡一会儿,让其他线程工作)。
相反,wait()是一种线程(或消息)同步机制,它允许您通知没有存储引用(也没有关心)的线程。您可以将其视为一个发布-订阅模式(wait == subscribe and notify() == publish)。基本上,使用notify()你是在发送一条消息(甚至可能根本没有收到,通常情况下你并不关心)。
总而言之,通常使用sleep()进行时间同步,使用wait()进行多线程同步。
它们可以在底层操作系统中以同样的方式实现,也可以完全不实现(因为以前版本的Java没有真正的多线程;可能一些小的虚拟机也不这样做)。别忘了Java是在VM上运行的,所以你的代码会根据所运行的VM/OS/HW的不同而转换成不同的东西。
从oracle文档页面的wait()方法的对象:
public final void wait()
导致当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法。换句话说,这个方法的行为就像简单地执行调用wait(0)一样。 当前线程必须拥有该对象的监视器。线程释放该监视器的所有权并等待,直到另一个线程通知等待该对象监视器的线程被唤醒 可能会出现中断和虚假唤醒 此方法只能由该对象的监视器的所有者的线程调用
这个方法抛出
IllegalMonitorStateException -如果当前线程不是对象的监视器的所有者。 InterruptedException——如果任何线程在当前线程等待通知之前或期间中断了当前线程。抛出此异常时,当前线程的中断状态将被清除。
从oracle文档页关于Thread类的sleep()方法:
public static void sleep(long millis)
使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,这取决于系统计时器和调度器的精度和准确性。 线程不会失去任何监视器的所有权。
这个方法抛出:
IllegalArgumentException -如果millis的值为负 InterruptedException -如果任何线程中断了当前线程。抛出此异常时,当前线程的中断状态将被清除。
其他关键区别:
Wait()是一个非静态方法(实例方法),不同于静态方法sleep()(类方法)。
你是正确的- Sleep()导致线程“睡眠”,CPU将离开并处理其他线程(也称为上下文切换),而我认为Wait保持CPU处理当前线程。
我们两者都有,因为尽管让其他人在你不使用CPU时使用它似乎是明智的,但实际上上下文切换是有开销的——取决于睡眠的时长,在CPU周期中切换线程可能比简单地让你的线程在几毫秒内什么都不做要昂贵得多。
还要注意,睡眠会强制进行上下文切换。
此外——通常情况下控制上下文切换是不可能的——在等待期间,操作系统可能(并且会有更长的等待)选择处理其他线程。