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



我是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));
            }
        }
    }
}

最新更新