关于多线程中的wait/notify机制

我在测试一个消费者/生产者场景:
生产者与消费者共享一个ArrayList,且规定里面只能存一个字符串。
这是生产者和消费者的实现方法的类

public class myTask {
    private List list = new ArrayList();
    synchronized public void push() {
        try {
            if(list.size() == 1) {
                this.wait();
            }
            list.add("数值为:" + Math.random());
            this.notify();
            System.out.println("生产者执行完毕,当前数组长度:" + list.size());
        }catch (InterruptedException e) {   e.printStackTrace(); }
    }

    synchronized public String pop() {
        String value = "";
        try {
            if(list.size() == 0) {
                System.out.println("消费者线程:" + Thread.currentThread().getName() + "进入等待");
                this.wait();
            }
            value = "" + list.get(0);
            list.remove(0);
            this.notify();
            System.out.println("消费者执行完毕,当前数组长度:" + list.size());
        }catch (InterruptedException e) {   e.printStackTrace(); }
        return value;
    }
}

这是生产者和消费者

public class Producer {
    private myTask task;

    public Producer(myTask task) {
        this.task = task;
    }

    public void pushTask() {
      task.push();
    }
}
public class Customer {
    private myTask task;

    public Customer(myTask task) {
        this.task = task;
    }

    public void popTask() {
        System.out.println("消费者取出:" + task.pop()) ;
    }
}

这是两者的线程类

public class producerThread extends Thread{
    private Producer producer;

    public producerThread(Producer producer) {
        this.producer = producer;
    }

    @Override
    public void run() {
       while (true) {
           producer.pushTask();
       }
    }
}
public class customerThread extends Thread{
    private Customer customer;

    public customerThread(Customer customer) {
        this.customer = customer;
    }

    @Override
    public void run() {
        while (true) {
            customer.popTask();
        }
    }
}

以及测试的类

public class Run {
    public static void main(String[] args) throws InterruptedException{
           myTask task = new myTask();

           Producer producer = new Producer(task);
           Customer customer1 = new Customer(task);
           Customer customer2 = new Customer(task);
           Customer customer3 = new Customer(task);
           Customer customer4 = new Customer(task);

           producerThread producerThread1 = new producerThread(producer);
           customerThread customerThread1 = new customerThread(customer1);
           customerThread customerThread2 = new customerThread(customer2);
           customerThread customerThread3 = new customerThread(customer3);
           customerThread customerThread4 = new customerThread(customer4);


           customerThread1.start();
           customerThread2.start();
           customerThread3.start();
           customerThread4.start();
           producerThread1.start();
    }
}

我在运行后输出如下:
2.png

这几段代码是书上的代码,我不清楚为什么消费者Thread-2会执行 if判断代码段下面的语句,不是应该判别出数组的长度等于0后就进入等待了吗?为什么还会执行下面?
书上的解释是条件发生改变时没有得到及时响应,解决办法是把if改为while。顺便我想问下两者的差别。

阅读 1.5k
1 个回答

按你的写法,pop()方法notify()的不仅可能唤醒生产者,也可能唤醒消费者,这么说你懂了吧...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题