Java线程等待和通知方法

标签 java multithreading wait notify

我正在学习 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/

相关文章:

java - 如何从服务器以编程方式登录网站

java - Google Web 工具包示例应用程序

Java - 从 Eclipse 到 Excel 从 SQL 查询

c - 实现网络电台 : trying to open '.au' file in c

python - 当一组任务依赖于另一组任务时,如何在 python 中同时完成两组任务?

c# - 这个指针算术真的是线程安全的吗?

java - 为什么调用方法来设置变量比在构造函数中正常设置变量更好?

c++ - sleep 或等待不会停止整个程序?

java - 实现等待和通知

Java让GUI等待计时器