Java wait() 和 notify() 无法正常工作

Java wait() and notify() not working properly

我是 Java 多线程的新手,我遇到了一个问题。

public class WaitAndNotify {

   private static List<String> strings = Collections.synchronizedList(new ArrayList<>());

   public static void main(String[] args) {
       new Operator().start();
       new Machine().start();
   }

   // Operator thread
   static class Operator extends Thread {
       @Override
       public void run() {
           Scanner scanner = new Scanner(System.in);
           while (true) {
               System.out.println("Operator is working");
               synchronized (strings) {
                   strings.add(scanner.nextLine());
                   strings.notify();
                   System.out.println("Notifying to machine");
               }
               try {
                   sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
       }
   }

   // Machine thread
   static class Machine extends Thread {
       @Override
       public void run() {
           while (strings.isEmpty()) {
               synchronized (strings) {
                   try {
                       strings.wait();
                       System.out.println("Machine is waiting");
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   System.out.println(strings.remove(0));
               }
           }
       }
   }
}

我有操作员和机器threads。我启动每个线程,当我在控制台中写东西时,它必须 notify 机器并且机器必须打印它。那行得通,但有时机器不打电话。当我删除 notify 之后的 thread.sleep() 部分时,它根本不起作用。

一切正常时的控制台。

Operator is working
Hi...               // That's our message that we write in console
Notifying to machine
Machine is waiting
Hi...              // Machine printed our message successfully after 1 second
Operator is working

如果删除 thread.sleep() 部分会怎样。

Operator is working
Hi...             // That's our message that we write in console
Notifying to machine
Operator is working

如您所见,机器不工作。我不知道也许它被锁定了或别的什么。那么谁能向我解释为什么当 thread.sleep() 被删除时机器不打印我们的消息?

当你移除睡眠时,机器必须等到

之后的锁被释放
System.out.println("Notifying to machine");

在那条线之后,机器和操作员都在争夺锁。如果操作员击败机器,那么它会在机器打印任何内容之前第二次要求输入。在这一点之后,机器将只能打印一次,然后退出 while 循环。因为它只从数组中删除 1 个元素,所以数组总是有超过 0 个元素。

以下版本工作正常

    static class Operator extends Thread {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("Operator is working");
            synchronized (strings) {
                System.out.println("Notifying to machine1");
                strings.add(scanner.nextLine());
                strings.notify();
                System.out.println("Notifying to machine2");
                try {
                    strings.wait();
                }catch (Exception ex){}
            }
        }
    }
}

// Machine thread
static class Machine extends Thread {
    @Override
    public void run() {
        while (strings.isEmpty()) {
            System.out.println("strings is empty");
            synchronized (strings) {
                strings.notify();
                try {
                    System.out.println("Machine is waiting 1");
                    strings.wait();
                    System.out.println("Machine is waiting 2");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(strings.remove(0));
            }
        }
    }
}