Java线程等待和通知方法

麦克风

我正在学习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 entered in FirstThread,因为第一个线程启动,调用notify()方法,然后第二个线程启动,调用wait()方法,并且不打印字符串“我在第二个线程中” 。

接下来的情况是,我逆转的位置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 entered in FirstThread,释放等待,并在控制台中打印I'm in the second thread出来。

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

我的最后一个问题是,为什么锁对象必须是静态的,因为如果删除静态修饰符,输出将始终是I've entered in FirstThread

我知道在加载类时会在JVM中加载静态字段,但是我无法理解锁对象的逻辑。

美娜

线程是按顺序启动的,并且理论上讲线程1将在线程2之前执行,尽管不能保证(尽管在这种简单情况下,可以肯定它是一致的,因为没有实际的或模拟的延误延迟)。

这就是为什么在线程2刚刚启动之前,它有机会等待随后被线程1通知的锁,而不必永远等待已经被通知一次的锁(因此,不进行打印)。

staticObject:要绑定你的[First/Second]Thread嵌套类实例Main,所以锁必须是常见的两种,如果你希望他们在同一个锁进行同步。

如果它是一个实例对象,则您的线程将访问并在另一个锁上同步,因为您的new Main()...惯用语将获得的两个实例,Main随后获得的两个实例lock

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章