gpt4 book ai didi

Java线程等待和通知方法

转载 作者:搜寻专家 更新时间:2023-11-01 02:06:10 25 4
gpt4 key购买 nike

我正在学习 OCJP,现在正在学习“线程”一章,我对等待和通知方法有一些疑问。我想我明白这里发生了什么,但我只是想确保我走的路是正确的。我写了这段代码作为例子:

package threads;

public class Main {

static Object lock = new Object();

public static void main(String[] args) {
new Main().new FirstThread().start();
new Main().new SecondThread().start();
}

class FirstThread extends Thread {
public void run() {
synchronized (lock) {
lock.notify();
System.out.println("I've entered in FirstThread");
}
}
}
class SecondThread extends Thread {
public void run() {
synchronized (lock) {
try {
lock.wait();
System.out.println("I'm in the second thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

在这个例子中控制台输出是I've enter in FirstThread,因为第一个线程启动,notify()方法被调用,然后第二个线程启动,wait()方法是被调用并且字符串“I'm in the second thread”没有被打印出来。

下一个场景是我将 new Main().new FirstThread().start();new Main().new SecondThread().start( ); 输出是

I've entered in FirstThread
I'm in the second thread

因为第二个线程启动,wait()方法被调用,然后第一个线程启动,notify()方法被调用,控制台打印I've enter in FirstThread,等待已发布,I'm in the second thread 打印在控制台中。

发生这种情况是因为计算机速度如此之快并且线程按顺序运行吗?在我看来,理论上可以首先调用第二个 start() 方法是吗?

我的最后一个问题是,为什么锁定对象必须是静态的,因为如果我删除静态修饰符,输出总是我已经进入 FirstThread

我知道JVM在类加载的时候会加载静态字段,但是我无法理解lock Object的逻辑。

最佳答案

线程是按顺序启动的,理论上线程 1 会在线程 2 之前执行,尽管它不能保证(但很确定在这个简单的情况下它会是一致的,因为没有真正的或模拟的偶然延迟)。

这就是为什么当线程 2 稍微早一点启动时,它有机会等待随后(由线程 1)通知的锁,而不是永远等待已经通知过一次的锁(因此,不打印).

关于staticObject : 你正在绑定(bind)你的 [First/Second]Thread Main实例 的嵌套类,因此如果您希望它们在同一个锁上同步,则锁必须对两者都是通用的。

如果它是一个实例对象,您的线程将在不同的锁上访问和同步,就像您的 new Main()... idiom 会得到两个 Main 的实例随后是 lock 的两个实例.

关于Java线程等待和通知方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32591479/

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