线程中的wait()和sleep()有什么区别?

我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?

为什么我们同时使用wait()和sleep()?

它们的实现在较低级别上有什么不同?


当前回答

Wait()是在同步方法中给出的 而sleep()是在非同步方法中给出的,因为wait()方法会释放对象上的锁,而sleep()或yield()会释放对象上的锁。

其他回答

这是一个非常简单的问题,因为这两种方法有完全不同的用途。

主要的区别是等待释放锁或监视器,而sleep在等待时不释放任何锁或监视器。Wait用于线程间通信,而sleep用于执行时引入暂停。

这只是一个清晰而基本的解释,如果你想了解更多,请继续阅读。

在wait()方法的情况下,线程进入等待状态,它不会自动返回,直到我们调用notify()方法(或notifyAll()如果你有多个线程处于等待状态,你想唤醒所有这些线程)。您需要同步或对象锁或类锁来访问wait()或notify()或notifyAll()方法。还有一件事,wait()方法用于线程间通信,因为如果一个线程处于等待状态,您将需要另一个线程来唤醒该线程。

但是对于sleep(),这是一个用于将进程保持几秒钟或您想要的时间的方法。因为您不需要调用任何notify()或notifyAll()方法来取回线程。或者你不需要任何其他线程来回调那个线程。比如,如果你想让某些事情在几秒钟后发生,比如在游戏中,在用户轮到自己之后,你想让用户等待直到电脑开始运行,那么你可以使用sleep()方法。

还有一个在面试中经常被问到的更重要的区别:sleep()属于Thread类,wait()属于Object类。

这些就是sleep()和wait()之间的所有区别。

这两个方法之间有一个相似之处:它们都是checked语句,所以你需要try catch或throws来访问这些方法。

我希望这对你有所帮助。

在我看来,这两种机制之间的主要区别在于,睡眠/中断是处理线程的最基本方式,而等待/通知是一种抽象,旨在使线程间的通信更容易。这意味着睡眠/中断可以做任何事情,但这个特定的任务更难完成。

为什么等待/通知更合适?以下是一些个人考虑:

它加强了中央集权。它允许使用单个共享对象协调一组线程之间的通信。这大大简化了工作。 它强制同步。因为它使程序员将等待/通知调用包装在同步块中。 它与线程的起源和编号无关。使用这种方法,您可以任意添加更多线程,而无需编辑其他线程或跟踪现有线程。如果使用sleep/interrupt,首先需要保留对休眠线程的引用,然后手动逐个中断它们。

一个来自现实生活的例子很好地解释了这一点,一个经典的餐厅和员工之间用来沟通的方法:服务员把顾客的要求放在一个中心的地方(一块软木板,一张桌子等),摇铃,然后厨房的工人来接受这些要求。一旦有菜准备好了,厨房工作人员就会再次按铃,让服务员知道并把菜送到顾客面前。

来源:http://www.jguru.com/faq/view.jsp?EID=47127

thread .sleep()将当前线程发送到“不可运行”状态 在一段时间内。线程保留它所获得的监视器 ——也就是说,如果线程当前在一个同步块或方法中,其他线程不能进入这个块或方法。如果另一个线程调用t.interrupt(),它将唤醒正在睡觉的线程。 注意,sleep是一个静态方法,这意味着它总是有影响 当前线程(正在执行sleep方法的线程)。一个 常见的错误是调用t.sleep(),其中t是另一个线程; 即使这样,当前线程也会休眠,而不是t线程。 T.suspend()已弃用。使用它可以暂停其他线程 而不是当前线程。挂起的线程保存其所有监视器和 因为这个状态是不可中断的,所以很容易死锁。 object.wait()将当前线程发送到“不可运行”状态, 类似于sleep(),但有一点不同。在对象上调用Wait,而不是 线程;我们称这个对象为“锁对象”。在lock.wait()之前 调用时,当前线程必须同步锁对象;wait () 然后释放这个锁,并将线程添加到“等待列表” 与锁关联。上的另一个线程可以同步 相同的锁对象并调用lock.notify()。这唤醒了原始的, 等待线程。基本上,wait()/notify()就像 Sleep ()/interrupt(),只有活动线程不需要直接 指向睡眠线程的指针,但仅指向共享锁对象。

wait()必须被synchronized包围,当线程进入synchronized块或方法时,它意味着获得锁,所以它不阻塞,调用wait意味着释放锁,所以它退出synchronized然后阻塞,thread .sleep()导致当前线程在指定的时间内暂停执行。线程不会失去任何监视器的所有权

从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()(类方法)。