如何用交错线程停止我的程序

How to stop my program with interleaved thread

在那里重新学习多线程 :) 我正在尝试使用两个线程交替打印偶数和奇数,直到 50。

public class Threading {

    private static final Object lock = new Object();
    private static int i = 0;

    public static void main(String[] args) {
        new Thread(() -> {
            while(i <= 50) {
                synchronized (lock) {
                    System.out.println("A :" + i++);
                    try {
                        lock.notify();
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(() -> {
            while(i < 50) {
                synchronized (lock) {
                    System.out.println("B :" + i++);
                    try {
                        lock.notify();
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

这很好用并输出:

A :0
B :1
...
A :48
B :49
A :50

但是程序并没有停止,我不知道为什么。

我的理解是,当 A 打印 50 时,它释放 B 的锁,然后 B 的条件不成立,它释放锁,然后 A 不应该为真,因此两个线程完成了它们的工作。

所以我的推理可能有问题 :) 谁能给我解释一下?

让我们做一个线程转储:

"Thread-0@617" prio=5 tid=0xe nid=NA waiting
  java.lang.Thread.State: WAITING
      at java.lang.Object.wait(Object.java:-1)
      at java.lang.Object.wait(Object.java:502)
      at com.boris.testbench.App.lambda$main[=10=](App.java:22)
      at com.boris.testbench.App$$Lambda.1330278544.run(Unknown Source:-1)
      at java.lang.Thread.run(Thread.java:745)

我代码中的第 22 行是 lock.wait() 用于顶级线程 (A),事件顺序:

  • A 打印 "A:50"
  • A 通知所有人
  • A 等待 lock
  • B 唤醒并退出

因此您 A 处于锁定状态,无法唤醒它。