gpt4 book ai didi

java - OCJP 转储线程同步方法

转载 作者:太空宇宙 更新时间:2023-11-04 13:19:31 25 4
gpt4 key购买 nike

您好,我正在处理 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。任何人都可以得到正确的答案并为我提供解释吗?

最佳答案

这里B肯定是正确的。请参阅 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.

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

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

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. One of the following actions occurs:

  • If n is zero (i.e., thread t does not already possess the lock for target m), then an IllegalMonitorStateException is thrown.

  • 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.

  • If thread t is interrupted, then an InterruptedException is thrown and t's interruption status is set to false.

  • Otherwise, the following sequence occurs: (...)

因此没有严格定义首先检查哪些情况。实际上,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. “TimeoutException”是假的。如果传入的超时等待到期,该方法将正常返回。

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

E.另一个线程所做的任何事情都无法使该线程在写入时正常完成。

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

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

关于java - OCJP 转储线程同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33225389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com