我正在尝试使用等待和通知方法来实现生产者使用者。生产者线程将一些值放入数组列表的公共容器中。现在,从头开始,如果消费者线程在列表上获得了锁定,它将检查列表的大小,如果大小为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/