gpt4 book ai didi

java - 关于Java多线程使用notify()方法的两个问题

转载 作者:行者123 更新时间:2023-11-30 06:25:09 25 4
gpt4 key购买 nike

代码:

public class NotifyAndWaitTest2 implements Runnable {
public int i = 0;
public Object lock;
public SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");

public NotifyAndWaitTest2(Object o) {
this.lock = o;
}

@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " enter the SYNCHRONIZED block --- "+ sdf.format(new Date()));
try {
while (i < 9) {
Thread.sleep(500);
lock.notify();
lock.wait();
System.out.println(Thread.currentThread().getName() + " say:" + i++ + " --- " + sdf.format(new Date()));
}
lock.notify();
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
Object lock = new Object();
NotifyAndWaitTest2 test = new NotifyAndWaitTest2(lock);
Thread t1 = new Thread(test,"Thread A");
Thread t2 = new Thread(test,"Thread B");
Thread t3 = new Thread(test,"Thread C");
Thread t4 = new Thread(test,"Thread D");
t1.start();
t2.start();
t3.start();
t4.start();
}
}

结果:

Thread A enter the SYNCHRONIZED block --- 10:47:07.242
Thread B enter the SYNCHRONIZED block --- 10:47:07.743
Thread C enter the SYNCHRONIZED block --- 10:47:08.243
Thread D enter the SYNCHRONIZED block --- 10:47:08.743
Thread C say:0 --- 10:47:09.243
Thread D say:1 --- 10:47:09.744
Thread C say:2 --- 10:47:10.244
Thread D say:3 --- 10:47:10.744
Thread C say:4 --- 10:47:11.245
Thread D say:5 --- 10:47:11.745
Thread C say:6 --- 10:47:12.246
Thread D say:7 --- 10:47:12.746
Thread C say:8 --- 10:47:13.247
Thread D say:9 --- 10:47:13.247
Thread B say:10 --- 10:47:13.247
Thread A say:11 --- 10:47:13.247

该代码在jdk1.7和jdk1.8中执行结果相同。

我的问题:

  • 线程A和线程B进入SYNCHRONIZED block 并调用wait()方法后,为什么是线程C和线程D进入,而不是线程A说i,然后线程B说i?进入同步块(synchronized block)的优先级是否高于刚刚调用wait()方法的线程?

  • 为什么调用notify()方法只是唤醒最后调用wait()方法的线程?就像线程C和线程D一样,互相通知,互相等待,为什么不让其他线程等待呢?就像线程 A 和线程 B 一样。

我认为它应该是随机的,例如

Thread A enter the SYNCHRONIZED block
Thread B enter the SYNCHRONIZED block
Thread A say:0
Thread C enter the SYNCHRONIZED block
Thread B say:1
Thread A say:2
Thread D enter the SYNCHRONIZED block
Thread B say:3
Thread C say:4

最佳答案

问题 1:

After thread A and thread B enter SYNCHRONIZED block and call the wait() method, why is thread C and thread D entering instead of thread A say i and then thread B say i? Is the priority of entering the sync block higher than the thread that just called wait() method?

这就是 Javadoc关于等待/通知的说明:

The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.

这意味着,当线程 B 调用 notify 时,线程 A 将无法保证继续执行,并且线程 A 需要与在同步块(synchronized block)开始处等待的线程 C 和 D 进行竞争。在您的情况下,实现仅优先考虑线程 C 和 D。这就是您看到此输出的原因:

Thread A enter the SYNCHRONIZED block --- 10:47:07.242
Thread B enter the SYNCHRONIZED block --- 10:47:07.743
Thread C enter the SYNCHRONIZED block --- 10:47:08.243
Thread D enter the SYNCHRONIZED block --- 10:47:08.743

问题2:

Why called notify() method just wake up the lastest thread that called wait() method? just like the thread C and thread D, notify each other and wait for each other, why not any other waiting thread? like thread A and thread B.

同样,Java 规范不保证优先级。恰好从线程 D 调用 notify 唤醒了线程 C(它与线程 A 和 B 一起等待锁定),并在打印“say”语句并 hibernate 后从线程 C 调用for 500ms 唤醒线程 D(它再次与线程 A 和 B 一起等待锁),直到它们退出 while 循环和同步块(synchronized block),从而首先将锁释放给线程 B,然后释放给线程 A。

我运行的示例输出:

Thread A enter the SYNCHRONIZED block --- 09:35:59.836
Thread D enter the SYNCHRONIZED block --- 09:36:00.336
Thread C enter the SYNCHRONIZED block --- 09:36:00.836
Thread B enter the SYNCHRONIZED block --- 09:36:01.336
Thread C say:0 --- 09:36:01.836
Thread B say:1 --- 09:36:02.337
Thread C say:2 --- 09:36:02.837
Thread B say:3 --- 09:36:03.337
Thread C say:4 --- 09:36:03.837
Thread B say:5 --- 09:36:04.337
Thread C say:6 --- 09:36:04.837
Thread B say:7 --- 09:36:05.337
Thread C say:8 --- 09:36:05.837
Thread B say:9 --- 09:36:05.837
Thread D say:10 --- 09:36:05.837
Thread A say:11 --- 09:36:05.838

关于java - 关于Java多线程使用notify()方法的两个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47321030/

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