您好我正在处理SCJP转储,但现在我遇到了问题。这是一个问题:
void waitForSignal(){
Object obj = new Object();
synchronized(Thread.currentThread()){
obj.wait();
obj.notify();
}
}
哪种说法属实?
一个。此代码可以抛出InterruptedException
B中。此代码可以抛出illegalMonitorStateException
℃。此代码可在十分钟后抛出TimeoutException
d。颠倒obj.wait()和obj.notify()的顺序可能导致此方法正常完成
电子。从另一个线程调用notify()或notifyAll()可能会导致此方法正常完成
F。除非" obj.wait()"否则此代码不会编译。替换为"((Thread)obj).wait()"
我发现在一个转储文件中答案是A,而在另一个转储中答案是B.任何人都可以得到正确答案并为我提供解释吗?
答案 0 :(得分:0)
这里肯定B是正确的。请参阅IllegalMonitorStateException的API文档:
抛出此异常表示某个线程试图在对象的监视器上等待,或者在没有指定监视器的情况下通知在对象监视器上等待的其他线程。
获取的监视器是当前线程(顺便说一句,API文档警告不要这样做)。在obj上调用wait和notify方法,它们应该在当前线程对象上调用。
一个。 Object#wait可以抛出InterruptedException。这是否与实现有关,language spec说:
让线程t成为对象m上执行wait方法的线程,并且让n为t上的t锁定动作的数量,这些动作与解锁动作没有匹配。发生以下操作之一:
如果n为零(即,线程t尚未拥有目标m的锁定),则抛出IllegalMonitorStateException。
如果这是一个定时等待且nanosecs参数不在0-999999范围内或者millisecs参数为负数,则抛出IllegalArgumentException。
如果线程t被中断,则抛出InterruptedException,并将t的中断状态设置为false。
否则,将发生以下序列:(...)
因此没有严格定义首先检查哪些案例。实际上,InterruptedException并不会在Oracle或IBM JDK中抛出,IllegalMonitorStateException也是如此。
但是这段代码本身不会导致InterruptedException,需要在线程上调用中断。我用来尝试这个的代码是:
public class Test implements Runnable {
public void run() {
Object obj = new Object();
Thread.currentThread().interrupt();
try {
synchronized(Thread.currentThread()) {
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Thread(new Test()).start();
}
}
所以A在理论上可能是正确的。认证测试题需要相当明确,规范有点含糊不清,这让我觉得这不是一个很好的测试问题。
℃。 " TimeoutException异常"是虚假的。如果超时传递的等待到期,则方法正常返回。
d。颠倒等待和通知电话的顺序并不重要,它们都有相同的要求。
电子。另一个线程没有做任何事情可以使这个线程在写入时正常完成。
F。方法wait在Object上,而不是Thread,不需要强制转换。
鉴于B绝对是正确的,它描述了Java程序员需要理解的一个重要点,而A基于对规范的模糊狡辩,如果你只选择一个答案,我建议B.