Java Producer/Consumer 并发问题 - 尝试读取对象时出现 NoSuchElementFound 异常
Java Producer/Consumer Concurrency Issue - NoSuchElementFound Exception while trying to read objects
我们有这个生产者消费者的实现。
有时我们会在 readRecord() 方法中得到 NoSuchElementException。
理想情况下,这不应该发生,因为有一个 if 语句,并且该方法是同步的,这确保在任何时间点只执行一个线程。
但我们仍然得到 NoSuchElementException。有人可以指导我吗?
import java.util.LinkedList;
public class Listner{
private LinkedList<Object> objList = new LinkedList<Object>();
private Object listLock = new Object();
public void writeRecord(Object obj){
synchronized(listLock) {
objList.add(obj);
}
}
public synchronized Object readRecord(){
Object obj = null;
if( !objList.isEmpty() )
obj = objList.removeFirst();
return obj;
}
}
你的 readRecord
是同步的,所以一次最多可以有一个 readRecord
,但是没有什么可以阻止 readRecord
和 writeRecord
运行 并发,因为它们锁定在不同的对象上。如果碰巧 writeRecord
正在添加记录,那么 isEmpty
returns false,但是 removeFirst
找不到元素,因为 writeRecord
还没有完成添加后,您会得到该异常。
在 readRecord
中同步 listLock
,或者删除 listLock
并将两种方法声明为同步以修复它。
我们有这个生产者消费者的实现。 有时我们会在 readRecord() 方法中得到 NoSuchElementException。 理想情况下,这不应该发生,因为有一个 if 语句,并且该方法是同步的,这确保在任何时间点只执行一个线程。 但我们仍然得到 NoSuchElementException。有人可以指导我吗?
import java.util.LinkedList;
public class Listner{
private LinkedList<Object> objList = new LinkedList<Object>();
private Object listLock = new Object();
public void writeRecord(Object obj){
synchronized(listLock) {
objList.add(obj);
}
}
public synchronized Object readRecord(){
Object obj = null;
if( !objList.isEmpty() )
obj = objList.removeFirst();
return obj;
}
}
你的 readRecord
是同步的,所以一次最多可以有一个 readRecord
,但是没有什么可以阻止 readRecord
和 writeRecord
运行 并发,因为它们锁定在不同的对象上。如果碰巧 writeRecord
正在添加记录,那么 isEmpty
returns false,但是 removeFirst
找不到元素,因为 writeRecord
还没有完成添加后,您会得到该异常。
在 readRecord
中同步 listLock
,或者删除 listLock
并将两种方法声明为同步以修复它。