gpt4 book ai didi

java - wait() 不会被notifyAll() 中断

转载 作者:行者123 更新时间:2023-12-01 11:40:04 25 4
gpt4 key购买 nike

我制作了以下代码示例,用于测试同一锁定对象的 wait()notifyAll()。接收方线程正在等待锁定的对象,而发送方线程则激活 notifyAll()

public class MonitorState {

private static complexObj lock = new complexObj();

public static void main(String[] args) {
writeLog("Main - \tLocker name = " + lock.getName());
writeLog("Main - \tLocker code = " + lock.getCode());
try {
Thread receiver = new Receiver();
Thread sender = new Sender();

receiver.start();
sender.start();

Thread.sleep(5000);
writeLog("Main - \tLocker name = " + lock.getName());
writeLog("Main - \tLocker code = " + lock.getCode());
}
catch (Exception e) {
writeLog(e.getMessage());
e.printStackTrace();
}
}

private static void writeLog(String msg) {
Date time = new Date(System.currentTimeMillis());
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss.S");
System.out.println(df.format(time) + " " + msg);
}

// locking object
private static class complexObj {
private String name = "complexObj";
private Integer code = 0;

public complexObj() {
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}

private static class Receiver extends Thread {
public Receiver() {
}

@Override
public void run() {
int timeout = 100;
try{
synchronized (lock) {
writeLog("Receiver - Waiting for " + timeout + " ms.");
lock.wait(timeout);
}
}
catch (InterruptedException e) {
writeLog("Receiver - Interrupted.");
}
writeLog("Receiver - Timed out.");
writeLog("Receiver - Locker code = " + lock.getCode());
if (lock.getCode() == 0) {
writeLog("Receiver - Setting values into the locker.");
lock.setName("Receiver");
lock.setCode(2);
}

}
}

private static class Sender extends Thread {
public Sender() {
}

@Override
public void run() {
synchronized (lock) {
try {
int sleepTime = 3000;
writeLog("Sender - \tSleeping for " + sleepTime + " ms.");
sleep(sleepTime);
writeLog("Sender - \tSetting values into the locker.");
lock.setName("Sender");
lock.setCode(1);
lock.notifyAll();
}
catch (InterruptedException e) {
writeLog("Sender - \tInterrupted.");
}
}
}
}

}

输出为:

 16:17:52.191 Main -    Locker name = complexObj
16:17:52.237 Main - Locker code = 0
16:17:52.237 Receiver - Waiting for 4000 ms.
16:17:52.238 Sender - Sleeping for 3000 ms.
16:17:55.238 Sender - Setting values into the locker.
16:17:55.238 Receiver - Timed out.
16:17:55.238 Receiver - Locker code = 1
16:17:57.237 Main - Locker name = Sender
16:17:57.237 Main - Locker code = 1

我的问题是 - 为什么接收方没有收到“已中断”消息?

第二个问题:如果我将接收器线程的等待时间更改为 100ms,则输出为:

16:31:21.522 Main -     Locker name = complexObj
16:31:21.571 Main - Locker code = 0
16:31:21.571 Receiver - Waiting for 100 ms.
16:31:21.571 Sender - Sleeping for 3000 ms.
16:31:24.572 Sender - Setting values into the locker.
16:31:24.572 Receiver - Timed out.
16:31:24.572 Receiver - Locker code = 1
16:31:26.571 Main - Locker name = Sender
16:31:26.571 Main - Locker code = 1

查看时间戳,您会发现接收方花了 3 秒才收到“超时”消息,而不是应有的 100 毫秒。3秒是发送者在使用notifyAll()之前处于 Activity 状态的时间。你能解释一下为什么是 3 秒而不是 100 毫秒吗?

最佳答案

当锁被通知时,方法wait只是返回,不会抛出异常。 InterruptException是在使用Thread.interrupt()中断线程时抛出的,而不是在通知锁时抛出的。

关于java - wait() 不会被notifyAll() 中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29606756/

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