我正在尝试使用等待和通知方法来实现生产者使用者。生产者线程将一些值放入数组列表的公共容器中。现在,从头开始,如果消费者线程在列表上获得了锁定,它将检查列表的大小,如果大小为0,则它​​将进入等待状态。现在,生产者线程将第一个值放入循环中,并调用Notify方法,因此,现在消费者线程应获取通知并使用该值。再次,生产者线程应该恢复并开始for循环的下一次迭代,但是这没有发生。生产者内部的for循环将首先执行,然后运行消费者代码。

请指导我在网上搜索了很多我想念的东西,但是发现了更复杂的实现。

Producer.java

package com.multithreading;

import java.util.List;

public class Producer implements Runnable {

public List<Integer> commonObject;

Producer(List<Integer> commonObject) {
    this.commonObject = commonObject;
}

@Override
public void run() {
    synchronized (commonObject) {
        System.out.println("First Thread got the lock");
        for (int i = 0; i < 500; i++) {
            System.out.println("First Thread producing value");
            commonObject.add(i);
            System.out.println("First Thread notified");
            commonObject.notifyAll();
        }
    }

}

}


消费者.java

package com.multithreading;

import java.util.List;

public class Consumer implements Runnable {

public List<Integer> commonObject;

Consumer(List<Integer> commonObject) {
    this.commonObject = commonObject;
}

@Override
public void run() {
    synchronized (commonObject) {
        System.out.println("Second Thread got the lock");
        if (commonObject.size() == 0) {
            try {
                System.out.println("Second Thread going into Waiting state");
                commonObject.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("Second Thread Consuming Value");
            for (int i : commonObject) {
                System.out.println(i);
            }
        }
    }
}

}


ProducerConsumer.java

package com.multithreading;

import java.util.ArrayList;
import java.util.List;


public class ProducerConsumer {
public static void main(String [] arg){

    List<Integer> sharedObject=new ArrayList<Integer>();
    Producer producer=new Producer(sharedObject);
    Consumer consumer=new Consumer(sharedObject);
    Thread t1= new Thread(producer);
    Thread t2= new Thread(consumer);
    t1.start();
    t2.start();
}

}

最佳答案

我不确定这是否会有帮助,因为我不知道具体的问题是什么,但是可能是第二个线程无法使用这些值,因为您将代码中的“消费”部分放入了在else分支中,处于等待状态的线程将永远不会运行,因为它们处于if分支中?您应该将代码的“ consume”部分放在else之外,这样,当它们退出等待状态后,它们就可以“消费”值。

关于java - 生产者使用者代码问题(似乎Notify方法不会释放循环内的锁),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51330009/

10-12 02:09