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

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

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

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


当前回答

一个等待线程可以被另一个调用正在被等待的监视器上的notify线程“唤醒”,而一个睡眠线程则不能。另外,一个wait(和notify)必须发生在monitor对象上同步的块中,而sleep则不会:

Object mon = ...;
synchronized (mon) {
    mon.wait();
} 

此时,当前正在执行的线程等待并释放监视器。另一个线程可以

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

(在同一个mon对象上)和第一个线程(假设它是在监视器上等待的唯一线程)将被唤醒。

如果有多个线程在监视器上等待,您也可以调用notifyAll—这将唤醒所有线程。但是,只有一个线程能够获取监视器(记住,等待是在同步块中)并继续执行—其他线程将被阻塞,直到它们获得监视器的锁。

另一点是你在对象本身调用wait(即你在对象的监视器上调用wait),而你在线程上调用sleep。

还有一点是,你可以从wait中得到虚假的唤醒(例如,正在等待的线程没有明显的原因就恢复了)。你应该总是等待在某些条件下旋转,如下所示:

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

其他回答

你是正确的- Sleep()导致线程“睡眠”,CPU将离开并处理其他线程(也称为上下文切换),而我认为Wait保持CPU处理当前线程。

我们两者都有,因为尽管让其他人在你不使用CPU时使用它似乎是明智的,但实际上上下文切换是有开销的——取决于睡眠的时长,在CPU周期中切换线程可能比简单地让你的线程在几毫秒内什么都不做要昂贵得多。

还要注意,睡眠会强制进行上下文切换。

此外——通常情况下控制上下文切换是不可能的——在等待期间,操作系统可能(并且会有更长的等待)选择处理其他线程。

wait()是Object类的一个方法。 sleep()是Thread类的一个方法。 Sleep()允许线程进入睡眠状态x毫秒。 当线程进入睡眠状态时,它不会释放锁。 Wait()允许线程释放锁并进入挂起状态。 当notify()或notifAll()方法被激活时,该线程将处于活动状态 为同一个对象调用。

这些方法用于不同的事情。

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是起点…

来源: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(),只有活动线程不需要直接 指向睡眠线程的指针,但仅指向共享锁对象。

等待和睡觉是两回事:

在sleep()中,线程在指定的时间内停止工作。 在wait()中,线程停止工作,直到被等待的对象被通知,通常由其他线程通知。