[英]OCJP Dumps Thread Synchronized Method
嗨,我正在处理SCJP转储,但现在遇到了问题。 这是问题:
void waitForSignal(){
Object obj = new Object();
synchronized(Thread.currentThread()){
obj.wait();
obj.notify();
}
}
哪个论述是对的?
答:此代码可以引发InterruptedException
B.这段代码会抛出一个非法的MonitorStateException
C.此代码可以在十分钟后引发TimeoutException
D.颠倒obj.wait()和obj.notify()的顺序可能会导致此方法正常完成
E.从另一个线程调用notify()或notifyAll()可能导致此方法正常完成
F.除非将“ obj.wait()”替换为“((Thread)obj).wait()”,否则不会编译此代码。
我发现在一个转储文件中答案是A,而在另一个转储文件中答案是B。任何人都可以找到正确的答案并为我提供解释吗?
绝对B在这里是正确的。 请参阅IllegalMonitorStateException的API文档:
抛出该异常指示线程试图在对象的监视器上等待,或者通知其他线程在对象监视器上等待而没有拥有指定的监视器。
所获取的监视器是当前线程(顺便说一下,API文档警告不要这样做)。 在obj上调用了wait和notify方法,该方法应该在当前线程对象上调用。
答:Object#wait可以引发InterruptedException。 语言规范说:是否会发生这种情况取决于实现方式:
令线程t为在对象m上执行wait方法的线程,令n为t对m进行的,未与解锁动作匹配的锁定动作的数量。 发生以下操作之一:
如果n为零(即线程t尚未拥有对目标m的锁定),则将引发IllegalMonitorStateException。
如果这是定时等待,并且nanosecs参数不在0-999999范围内,或者millisecs参数为负,则抛出IllegalArgumentException。
如果线程t被中断,则抛出InterruptedException,并且t的中断状态设置为false。
否则,将发生以下顺序:(...)
因此,没有严格定义将首先检查哪些情况。 实际上,在Oracle或IBM JDK中不会抛出InterruptedException,而在IllegalMonitorStateException中会抛出InterruptedException。
但是此代码本身不会导致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在理论上可能是正确的。 认证测试问题必须合理明确,规范在这一点上有点模棱两可,这使我认为这不是一个很好的测试问题。
C.“ TimeoutException”是伪造的。 如果等待超时超时,则该方法正常返回。
D.反转等待和通知呼叫的顺序无关紧要,它们都有相同的要求。
E.另一个线程所做的任何事情都不能使该线程在编写时正常完成。
F.方法等待在对象而不是线程上,不需要强制转换。
鉴于B绝对是正确的,并且它描述了Java程序员需要理解的重要点,而A基于对规范的模糊理解,如果您只能选择一个答案,我建议B。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.