如何在Java中使用wait/notify正确同步2个不同对象上的2个线程?

rn0zuynd  于 2023-05-21  发布在  Java
关注(0)|答案(1)|浏览(87)

我正在学习Java中的同步。我知道这是一个很基本的问题,但我想不出来。
我有一个包含2个不同对象和2个线程的类。

class MyThreads {
    public final static Object den = new Object();
    public final static Object ada = new Object();

    public static Thread t1 = new Thread() {
        public void run() {
            System.out.println("Thread 1 den");
            System.out.println("Thread 1 ada");
        }
    };

    public static Thread t2 = new Thread() {
        public void run() {
              System.out.println("Thread 2 den");
              System.out.println("Thread 2 ada");
        }
    };
}

执行此代码后:

MyThreads.t1.start();
MyThreads.t2.start();

我应该得到:

Thread 1 den
Thread 2 den
Thread 1 ada
Thread 2 ada

我在这里挣扎。我不明白线程1是如何唤醒线程2的。

public static Thread t1 = new Thread() {
        public void run() {
            System.out.println("Thread 1 den");
            synchronized (den) {
                try {   
                    den.notifyAll();
                    den.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

public static Thread t2 = new Thread() {
        public void run() {
            synchronized (ada){
                        ada.wait();
//                     How to awake it?
                        }
        }
    };

我会感谢任何建议!

uqzxnwby

uqzxnwby1#

为了实现所需的输出,其中“Thread 1 den”在“Thread 2 den”之前打印,“Thread 1 ada”在“Thread 2 ada”之前打印,您可以使用wait()和notifyAll()方法来同步线程的执行。下面是代码的更新版本:

class MyThreads {
    public final static Object den = new Object();
    public final static Object ada = new Object();

    public static Thread t1 = new Thread() {
        public void run() {
            System.out.println("Thread 1 before Thread 2");
            synchronized (den) {
                try {
                    den.wait();  // Wait until den is notified
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Thread 1 den");
            
            synchronized (ada) {
                ada.notifyAll();  // Notify ada to wake up Thread 2
            }
        }
    };

    public static Thread t2 = new Thread() {
        public void run() {
            synchronized (den) {
                den.notifyAll();  // Notify den to wake up Thread 1
            }
            
            synchronized (ada) {
                try {
                    ada.wait();  // Wait until ada is notified
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Thread 2 ada");
        }
    };
}

在更新后的代码中,t1线程首先进入den上的synchronized块并调用den.wait()。这将导致t1等待,直到它被另一个线程通知。同时,t2线程被执行,它进入den上的synchronized块并调用den.notifyAll(),这唤醒了等待的t1线程。
t1被唤醒后,它打印“Thread 1 den”。然后,它进入ada上的synchronized块并调用ada.notifyAll(),这将唤醒等待的t2线程。
最后,t2被唤醒并打印“Thread 2 ada”。
通过使用wait()和notifyAll()方法沿着synchronized块,您可以控制线程之间的执行顺序并获得所需的输出。

相关问题