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

发布于 2022-09-12 01:48:15 字数 3282 浏览 14 评论 0

我在测试一个消费者/生产者场景:
生产者与消费者共享一个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。顺便我想问下两者的差别。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最美不过初阳 2022-09-19 01:48:15

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文