【问题标题】:OCJP Dumps Thread Synchronized MethodOCJP 转储线程同步方法
【发布时间】:2015-10-19 23:03:46
【问题描述】:

您好,我正在处理 SCJP 转储,但现在遇到了问题。问题来了:

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

哪种说法是正确的?

A.此代码可能会抛出 InterruptedException

B.此代码可能会抛出非法MonitorStateException

C.这段代码十分钟后会抛出 TimeoutException

D.颠倒 obj.wait() 和 obj.notify() 的顺序可能会导致该方法正常完成

E.从另一个线程调用 notify() 或 notifyAll() 可能会导致此方法正常完成

F。除非将“obj.wait()”替换为“((Thread) obj).wait()”,否则此代码不会编译

我发现在一个转储文件中答案是 A,而在另一个转储文件中答案是 B。谁能得到正确答案并为我提供解释?

【问题讨论】:

    标签: java multithreading scjp java-threads


    【解决方案1】:

    这里绝对 B 是正确的。请参阅IllegalMonitorStateException 的 API 文档:

    抛出以表明一个线程试图在一个对象的监视器上等待,或者通知其他线程在一个对象的监视器上等待而不拥有指定的监视器。

    获取的监视器是当前线程(顺便说一下,API 文档警告不要这样做)。 wait 和 notify 方法在 obj 上调用,它们应该在当前线程对象上调用。

    A. Object#wait 可以抛出 InterruptedException。这是否发生取决于实现,language spec 说:

    令线程 t 为对对象 m 执行等待方法的线程,设 n 为 t 对 m 的未与解锁动作匹配的锁定动作的数量。发生以下操作之一:

    • 如果 n 为零(即线程 t 尚未拥有目标 m 的锁),则抛出 IllegalMonitorStateException。

    • 如果这是一个定时等待且 nanosecs 参数不在 0-999999 范围内或 millisecs 参数为负数,则抛出 IllegalArgumentException。

    • 如果线程 t 被中断,则抛出 InterruptedException 并将 t 的中断状态设置为 false。

    • 否则会出现以下顺序:(...)

    因此没有严格定义首先检查哪些情况。实际上,Oracle 或 IBM JDK 中不会抛出 InterruptedException,而 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 可能是正确的。认证测试问题需要相当明确,规范对这一点有点模棱两可让我认为这不是一个很好的测试问题。

    C. “超时异常”是假的。如果传入超时的等待过期,则该方法正常返回。

    D.颠倒等待和通知调用的顺序并不重要,它们都有相同的要求。

    E.其他线程所做的任何事情都无法使该线程正常完成。

    F。方法 wait 是在 Object 上,而不是在 Thread 上,不需要强制转换。

    鉴于 B 绝对正确,并且它描述了 Java 程序员需要理解的一个重要点,而 A 是基于对规范的晦涩狡辩,如果你只能选择一个答案,我会推荐 B。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多