2016-11-10 8 views
0

Я пытаюсь создать собственный вариант BlockingQueue, основанный на одном из found here.Проблемы с реализацией 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) at java.lang.Thread.run (Неизвестный источник)

Я могу удалить ошибку, изменив размер == 0 на front == null, но он все равно не выводит то же самое.

+0

Возможный дубликат [Что такое исключение NullPointerException и как его исправить?] (Http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix -it) – bradimus

+0

@bradimus Функционально мой код должен вести себя одинаково, за исключением использования ранее существовавшей структуры списка, которую я разработал самостоятельно. Размер ++/- должен отражать эффекты примера, который я использовал. Тем не менее, он работает отлично, в то время как у меня есть ошибки. – generaltsao

ответ

0

В настоящее время, если вы звоните в remove(), последний раз удаляете последний элемент, вы получаете сообщение front == null, но end == //the last created node. Это означает, что следующий звонок по номеру add будет обновлять только end, а не front, и соответствующий звонок на remove() будет бросать ваш NPE.

Вы можете проверить front == null в конце remove() или изменить тест в add от end == null к size == 0 или front == null.

Как в стороне, если вы отправляете трассировку стека, полезно добавить комментарий, указывающий, какая строка в вашем фрагменте соответствует номерам строк в исключении.

 Смежные вопросы

  • Нет связанных вопросов^_^