Проблемы реализации BlockingQueue с нуля
Я пытаюсь построить свой собственный вариант 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());
}
};
Я получаю это исключение
Исключение в потоке "Thread-3" java.lang.NullPointerException в ThreadSafeContainer.remove(ThreadSafeContainer.java:52) в ThreadPractice$2.run(ThreadPractice.java:17) в java.lang.Thread.run(неизвестный источник)
Я могу удалить ошибку, изменив размер == 0 на front == null, но он все равно не выдает то же самое.
1 ответ
В настоящее время, если вызов remove()
когда-либо удаляет последний элемент, вы в конечном итоге front == null
но end == //the last created node
, Что означает следующий звонок add
будет только обновлять end
не front
и соответствующий вызов remove()
бросит ваш NPE.
Вы можете проверить front == null
в конце remove()
или измените тест в add
от end == null
в size == 0
или же front == null
,
Кроме того, если вы публикуете трассировку стека, полезно добавить комментарий, указывающий, какая строка в вашем фрагменте соответствует номерам строк в исключении.