简体   繁体   English

OCJP转储线程同步方法

[英]OCJP Dumps Thread Synchronized Method

Hi I am working on SCJP dumps but now I got a problem. 嗨,我正在处理SCJP转储,但现在遇到了问题。 Here is the question: 这是问题:

void waitForSignal(){
   Object obj = new Object();
   synchronized(Thread.currentThread()){
       obj.wait();
       obj.notify();
   }
}

Which statement is true? 哪个论述是对的?

A. This code can throw an InterruptedException 答:此代码可以引发InterruptedException

B. This code can throw an illegalMonitorStateException B.这段代码会抛出一个非法的MonitorStateException

C. This code can throw a TimeoutException after ten minutes C.此代码可以在十分钟后引发TimeoutException

D. Reversing the order of obj.wait() and obj.notify() might cause this method to complete normally D.颠倒obj.wait()和obj.notify()的顺序可能会导致此方法正常完成

E. A call to notify() or notifyAll() from another thread might cause this method to complete normally E.从另一个线程调用notify()或notifyAll()可能导致此方法正常完成

F. This code does NOT compile unless "obj.wait()" is replace with "((Thread) obj).wait()" F.除非将“ obj.wait()”替换为“((Thread)obj).wait()”,否则不会编译此代码。

I found that in one dump file the answer is A, while in another dump the answer is B. Can anyone get the right answer and provide explanantion for me? 我发现在一个转储文件中答案是A,而在另一个转储文件中答案是B。任何人都可以找到正确的答案并为我提供解释吗?

Definitely B is correct here. 绝对B在这里是正确的。 See the API documentation for IllegalMonitorStateException : 请参阅IllegalMonitorStateException的API文档:

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor. 抛出该异常指示线程试图在对象的监视器上等待,或者通知其他线程在对象监视器上等待而没有拥有指定的监视器。

The monitor acquired is the current thread (which the API documentation warns against doing, by the way). 所获取的监视器是当前线程(顺便说一下,API文档警告不要这样做)。 The methods wait and notify are called on obj, where they should have been called on the current thread object. 在obj上调用了wait和notify方法,该方法应该在当前线程对象上调用。

A. Object#wait can throw InterruptedException. 答:Object#wait可以引发InterruptedException。 Whether this happens is implementation-dependent, the language spec says: 语言规范说:是否会发生这种情况取决于实现方式:

Let thread t be the thread executing the wait method on object m, and let n be the number of lock actions by t on m that have not been matched by unlock actions. 令线程t为在对象m上执行wait方法的线程,令n为t对m进行的,未与解锁动作匹配的锁定动作的数量。 One of the following actions occurs: 发生以下操作之一:

  • If n is zero (ie, thread t does not already possess the lock for target m), then an IllegalMonitorStateException is thrown. 如果n为零(即线程t尚未拥有对目标m的锁定),则将引发IllegalMonitorStateException。

  • If this is a timed wait and the nanosecs argument is not in the range of 0-999999 or the millisecs argument is negative, then an IllegalArgumentException is thrown. 如果这是定时等待,并且nanosecs参数不在0-999999范围内,或者millisecs参数为负,则抛出IllegalArgumentException。

  • If thread t is interrupted, then an InterruptedException is thrown and t's interruption status is set to false. 如果线程t被中断,则抛出InterruptedException,并且t的中断状态设置为false。

  • Otherwise, the following sequence occurs: (...) 否则,将发生以下顺序:(...)

so it's not strictly defined which of these cases will be checked first. 因此,没有严格定义将首先检查哪些情况。 In practice InterruptedException doesn't get thrown in the Oracle or IBM JDKs, IllegalMonitorStateException does. 实际上,在Oracle或IBM JDK中不会抛出InterruptedException,而在IllegalMonitorStateException中会抛出InterruptedException。

But this code by itself won't cause an InterruptedException, something needs to call interrupt on the thread. 但是此代码本身不会导致InterruptedException,因此需要在线程上调用中断。 The code I used to try this out was: 我用来尝试的代码是:

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();
    }
}

So A might be correct in theory. 因此,A在理论上可能是正确的。 Certification test questions need to be reasonably clear-cut, that the spec is a little ambiguous about this point makes me think this is not a great test question. 认证测试问题必须合理明确,规范在这一点上有点模棱两可,这使我认为这不是一个很好的测试问题。

C. "TimeoutException" is bogus. C.“ TimeoutException”是伪造的。 If a wait with a timeout passed in expires the method returns normally. 如果等待超时超时,则该方法正常返回。

D. Reversing the order of the wait and notify calls doesn't matter, they both have the same requirement. D.反转等待和通知呼叫的顺序无关紧要,它们都有相同的要求。

E. Nothing done by another thread can make this thread complete normally as it is written. E.另一个线程所做的任何事情都不能使该线程在编写时正常完成。

F. The method wait is on Object, not Thread, no cast is required. F.方法等待在对象而不是线程上,不需要强制转换。

Given that B is definitely true and it describes an important point that needs to be understood by Java programmers, while A is based on obscure quibbling about the spec, if you can pick only one answer I'd recommend B. 鉴于B绝对是正确的,并且它描述了Java程序员需要理解的重要点,而A基于对规范的模糊理解,如果您只能选择一个答案,我建议B。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM