0

I'm trying to build my own variant of BlockingQueue based off the one found here.

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;
    }
}

But for some reason when I try to run threads like so

    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());
        }
    };      

I get this exception

Exception in thread "Thread-3" java.lang.NullPointerException at ThreadSafeContainer.remove(ThreadSafeContainer.java:52) at ThreadPractice$2.run(ThreadPractice.java:17) at java.lang.Thread.run(Unknown Source)

I can remove the error by changing the size == 0 to front == null but it still doesnt output the same.

  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – bradimus Nov 10 '16 at 19:17
  • @bradimus Functionally, my code should behave identically except instead of using a pre-existing list structure I've designed my own. The size++/-- should mirror the effects of the example I used. However his runs fine whereas mine has errors. – generaltsao Nov 10 '16 at 19:28

1 Answers1

0

Currently, if a call to remove() ever removes the last element, you end up with front == null but end == //the last created node. Which means the next call to add will only update end, not front, and the corresponding call to remove() will throw your NPE.

You can either check for front == null at the end of remove(), or change the test in add from end == null to size == 0 or front == null.

As an aside, if you're posting a stack trace, it's helpful to add a comment indicating which line in your snippet corresponds to the line numbers in the exception.

Sbodd
  • 11,279
  • 6
  • 41
  • 42