杭州IT培训
美国上市IT培训机构

400-111-8989

wait()和sleep()的区别

  • 时间:2018-04-12 14:26
  • 发布:杭州达内
  • 来源:企业笔试题

问题:

在线程里 wait() 和 sleep() 的区别?

我的理解是执行 wait() 语句后,该线程仍是运行态,并且会占用CPU,但是执行 sleep()后,该线程则不会占用CPU,对吗?

为什么需要 sleep() 和 wait() 两条语句:他们底层是如何实现的?

回答:

线程 在wait 后,可以被另一个拥有相同 synchronized 对象的线程,通过调用 notify 唤醒,而 sleep 不行。wait 和 otify 能正常执行的条件是(否则会抛异常):多个线程的代码,都包在synchronized块中,并且 synchronized 锁的对象需要是同一个。

如下所示:

Object mon = ...;

synchronized (mon) {

mon.wait();

}

上面这个线程调用了 wait后,会进入等待状态。这时另外一个线程可以这样做:

synchronized (mon) { mon.notify(); }

可以看到,synchronized锁对象,都是mon。因此,当第二个线程调用了 notify() 方法,第一个线程就会唤醒(假设有且仅有一个线程是被包在 synchronized (mon) 中且处于等待状态)。

如果有多个线程在等待(且synchronized 锁对象是同一个,如上例中的mon),则可以调用 notifyAll 来唤醒。但是,只有其中一个线程能抢到锁并继续执行(因为 wait 的线程都是在 synchronized 块内,需要争夺 synchronized 锁)。其他的线程会被锁住,直到他们依次获得锁。

再补充几点:

wait 方法由 Object 对象调用(例如:你可以让 synchronized 锁对象调用 wait ,如上面例子的mon.wait()),而 sleep 则由线程调用。

wait 之后,可能会伪唤醒(spurious wakeups)(正在waiting的线程,无故就被唤醒了,如遇到interrupted, timing out等情况)。因此,你需要多设置一些检查,如果不满足实际的运行条件,则继续等待,如下:

synchronized {

while (!condition) { mon.wait(); }

}

当线程调用 sleep 时,并没有释放对象锁,而 wait 则释放了对象锁:

synchronized(LOCK) {

Thread.sleep(1000); // LOCK is held

}

synchronized(LOCK) {

LOCK.wait(); // LOCK is not held}

最后,再小结一下:

sleep():“我已经完成了一个时间片,在n微秒前,请不要再给我一个时间片”。这时操作系统不会让这个线程做任何事情,直到sleep时间结束。

wait():"我已经完成了一个时间片,在其他线程调用notify()前,请不要再给我一个时间片)。这时操作系统不会安排这个线程继续运行,直到有人调用了notify()

预约申请免费试听课

怕钱不够?就业挣钱后再付学费!    怕学不会?从入学起,达内定制课程!     担心就业?达内多家实践企业供你挑选 !

【免责声明】本文部分系转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与联系我们,我们会予以更改或删除相关文章,以保证您的权益!"
上一篇:这个本地变量类型推断你肯定没见过
下一篇:Java工程师成神之路
  • 扫码领取资料

    回复关键字:视频资料

    免费领取 达内课程视频学习资料

  • 搜索抖音号

    搜索抖音号:1821685962

    免费领取达内课程视频学习资料

Copyright © 2021 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
江西省

贵州省

广西省

海南省