以下是我在维护的一些代码中看到的一段代码。
Object lock = new Object();
synchronized( lock )
{
try
{
lock.wait( 50000 );
Thread.sleep( 3000 );
}
catch(Exception ex)
{
}
}
开发人员希望暂停当前线程一段时间,并使用Object#wait作为机制。显然,由于这个原因,使用wait / notify协议是不好的形式;但是,调用wait(millisec)和Thread.sleep之间有什么重大区别吗?
答案 0 :(得分:4)
除了必须在等待之前获得一个监视器()之外,只要没有一个外部将会是.notify(),就不会有任何重大差异。
在古代Java代码中,您会看到人们使用wait()而不是Thread.sleep(),因为Thread.sleep()会在没有抢占式多任务处理的情况下冻结整个应用程序(我正在看你OS9)。从技术上讲,wait()也让你使用纳米分辨率等待,但实际上它们很少准确。
答案 1 :(得分:4)
请注意,在同步块中使用Object.wait()和Thread.sleep() 有一个关键区别:Thread.sleep()不释放锁定的监视器,所以没有 - 其他人可以成为监视器的所有者。
此外,Object.wait()不保证严格遵守指示的延迟。首先,在延迟过去之后,线程可能仍在等待同时成为监视所有者的另一个线程;并且它可能与等待抓住监视器的其他线程竞争。
其次,神秘的虚假唤醒,正如Java 6 API javadoc中描述的那样:
线程也可以在没有的情况下唤醒 被通知,中断或计时 一个所谓的虚假唤醒。
不太可能,使用Object.wait()的每一段代码都应该考虑它。
答案 2 :(得分:3)
你说使用wait / notify这是“显然”不好的形式,但我没有看到它有任何问题。无可否认地跟进sleep
电话是非常奇怪的(吞咽异常很糟糕),但我现在肯定使用Object.wait
作为“可破坏的睡眠”。
想象一下,你每分钟都有一个线程轮询资源,但是如果发生了某些事情你想要被唤醒(例如资源位置已经改变,或者计时器频率已经改变,或者程序想要以优雅的方式退出)。使用wait/notify
非常有效 - 它比从其他地方调用线程上的interrupt
更清晰,因为在您实际处理而不是等待时发生通知并不重要。