线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
当前回答
sleep()是一个用来保持进程几秒钟或你想要的时间的方法,但如果wait()方法线程处于等待状态,它不会自动返回,直到我们调用notify()或notifyAll()。
主要的区别是wait()释放锁或监视器,而sleep()在等待时不释放任何锁或监视器。Wait用于线程间通信,而sleep通常用于在执行时引入暂停。
thread .sleep()将当前线程发送到“不可运行”状态一段时间。线程保留它获得的监视器——也就是说,如果线程当前在一个同步块或方法中,没有其他线程可以进入这个块或方法。如果另一个线程调用t.interrupt(),它将唤醒正在睡觉的线程。注意,sleep是一个静态方法,这意味着它总是影响当前线程(正在执行sleep方法的线程)。一个常见的错误是调用t.sleep(),其中t是一个不同的线程;即使这样,当前线程也会休眠,而不是t线程。
object.wait()将当前线程发送到“Not Runnable”状态,就像sleep(),但是有一个扭曲。Wait被调用在对象上,而不是线程上;我们称这个对象为“锁对象”。在lock.wait()被调用之前,当前线程必须在锁对象上同步;Wait()然后释放这个锁,并将线程添加到与锁相关的“等待列表”中。稍后,另一个线程可以同步同一锁对象并调用lock.notify()。这将唤醒原始的等待线程。基本上,wait()/notify()类似于sleep()/interrupt(),只是活动线程不需要直接指向睡眠线程,而只需要指向共享锁对象。
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}
让我们对以上几点进行分类:
呼吁:
wait():调用一个对象;当前线程必须同步锁对象。 sleep():在线程上调用;总是当前执行线程。
同步:
wait():同步的多个线程逐个访问同一个对象。 Sleep():当同步的多个线程等待休眠线程的休眠。
持有锁:
Wait():释放锁,让其他对象有机会执行。 Sleep():如果指定超时或有人中断,则保持锁定至少t次。
唤醒条件:
wait():直到调用notify(), notifyAll()从对象 Sleep():直到至少超时或调用interrupt()。
用法:
Sleep():用于时间同步和; Wait():用于多线程同步。
参考:差别睡眠和等待
其他回答
这里有很多答案,但我找不到任何一个提到的语义区别。
这与线程本身无关;这两种方法都是必需的,因为它们支持非常不同的用例。
sleep()让线程像以前一样进入睡眠状态,它只是打包上下文并在预定义的时间内停止执行。因此,为了在到期时间之前唤醒它,您需要知道Thread引用。这在多线程环境中并不常见。它主要用于时间同步(例如,在3.5秒内醒来)和/或硬编码的公平性(只睡一会儿,让其他线程工作)。
相反,wait()是一种线程(或消息)同步机制,它允许您通知没有存储引用(也没有关心)的线程。您可以将其视为一个发布-订阅模式(wait == subscribe and notify() == publish)。基本上,使用notify()你是在发送一条消息(甚至可能根本没有收到,通常情况下你并不关心)。
总而言之,通常使用sleep()进行时间同步,使用wait()进行多线程同步。
它们可以在底层操作系统中以同样的方式实现,也可以完全不实现(因为以前版本的Java没有真正的多线程;可能一些小的虚拟机也不这样做)。别忘了Java是在VM上运行的,所以你的代码会根据所运行的VM/OS/HW的不同而转换成不同的东西。
这些方法用于不同的事情。
Thread.sleep(5000); // Wait until the time has passed.
Object.wait(); // Wait until some other thread tells me to wake up.
Thread.sleep(n)可以被中断,但是Object.wait()必须被通知。 可以指定等待的最大时间:Object.wait(5000),这样就可以使用wait,呃,睡眠,但这样你就不得不使用锁了。
这两种方法都不会在休眠/等待时使用cpu。
这些方法是使用本地代码实现的,使用类似的结构,但方式不同。
自己寻找:本机方法的源代码是否可用?文件/src/share/vm/prims/jvm.cpp是起点…
Wait()是在同步方法中给出的 而sleep()是在非同步方法中给出的,因为wait()方法会释放对象上的锁,而sleep()或yield()会释放对象上的锁。
wait()是Object类的一个方法。 sleep()是Thread类的一个方法。 Sleep()允许线程进入睡眠状态x毫秒。 当线程进入睡眠状态时,它不会释放锁。 Wait()允许线程释放锁并进入挂起状态。 当notify()或notifAll()方法被激活时,该线程将处于活动状态 为同一个对象调用。
让我们假设你正在听到歌曲。
只要当前歌曲正在运行,下一首歌就不会播放,即由下一首歌调用Sleep()
如果你完成了这首歌,它会停止,直到你选择播放按钮(notify())它才会播放,即由当前歌曲调用的wait()。
在这两种情况下,歌曲都进入等待状态。