[英]Problems implementing BlockingQueue from scratch
我正在嘗試根據此處找到的一個構建自己的BlockingQueue變體。
public class ThreadSafeContainer<E> {
private Node front;
private Node end;
private int capacity;
private int size;
public ThreadSafeContainer(int capacity) {
size = 0;
this.capacity = capacity;
}
public synchronized void add(E item) {
while (size == capacity) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (size == 0) {
notifyAll();
}
Node tmp = new Node(item);
if (end == null) {
front = tmp;
end = tmp;
} else {
end.next = tmp;
end = end.next;
}
size++;
}
public synchronized E remove() {
while (size == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (size == capacity) {
notifyAll();
}
E item = front.item;
front = front.next;
size--;
return item;
}
private class Node {
E item;
Node next;
public Node(E item) {
this.item = item;
}
}
但是由於某種原因,當我嘗試運行這樣的線程時
Thread thread1 = new Thread() {
public void run() {
queue.add(1);
queue.add(2);
}
};
Thread thread2 = new Thread() {
public void run() {
System.out.println(queue.remove());
System.out.println(queue.remove());
}
};
我得到這個例外
ThreadPractice $ 2.run(ThreadPractice.java:17)處ThreadSafeContainer.remove(ThreadSafeContainer.java:52)處的線程“ Thread-3”中的java.lang.NullPointerException(java.lang.Thread.run(未知源)
我可以通過將大小== 0更改為front == null來消除錯誤,但仍然不會輸出相同的錯誤。
當前,如果對remove()
的調用曾經刪除了最后一個元素,則最終結果是front == null
但是end == //the last created node
。 這意味着下一個add
調用將只更新end
,而不更新front
,而對remove()
的相應調用將引發您的NPE。
您可以在remove()
的末尾檢查front == null
,或者將add
的測試從end == null
更改為size == 0
或front == null
。
順便說一句,如果要發布堆棧跟蹤,添加注釋以指示代碼段中的哪一行與異常中的行號相對應會很有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.