Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(Linked)BlockingQueue.put(null) throws NullPointerException

I have checked the implementation, it does so intentionally

 public void put(E e) throws InterruptedException {
     if (e == null) throw new NullPointerException();

This surprise is not convenient for user (who wants to signal end of stream this way, for instance) and breaks the general contract with collections, which easily accept the null elements. What is the point of BlockingQueue to discriminate null elements? If nulls are so bad, might be we should refrain using them at all and enforce this low in JLS?

like image 572
Val Avatar asked May 31 '12 09:05

Val


People also ask

Is BlockingQueue thread safe?

BlockingQueue implementations are thread-safe. All queuing methods achieve their effects atomically using internal locks or other forms of concurrency control.

What is the use of BlockingQueue in Java?

BlockingQueue is a java Queue that support operations that wait for the queue to become non-empty when retrieving and removing an element, and wait for space to become available in the queue when adding an element.

What is array BlockingQueue in Java?

ArrayBlockingQueue class is a bounded blocking queue backed by an array. By bounded, it means that the size of the Queue is fixed. Once created, the capacity cannot be changed. Attempts to put an element into a full queue will result in the operation blocking.


1 Answers

Accepting nulls is not part of the Collection contract. Indeed, the Collection Javadoc specifically states:

Some collection implementations have restrictions on the elements that they may contain. For example, some implementations prohibit null elements, and some have restrictions on the types of their elements. Attempting to add an ineligible element throws an unchecked exception, typically NullPointerException or ClassCastException.

In many cases, adding null to a collection means there's a bug in your program somewhere, not that you put it in deliberately. For example, the Guava library (which I contribute to) makes the explicit decision to reject nulls from many of their collection implementations, specifically the immutable ones:

We did an exhaustive study on Google's internal code base that indicated that null elements were allowed in collections about 5% of the time, and the other 95% of cases were best served by failing fast on nulls.

There are generally workarounds that do accept nulls, but many collection implementations make the decision to reject nulls (which most users find helpful, as it helps them find bugs) and offer workarounds for the rare case where explicit nulls are appropriate.

In all honesty, I think the reason that LinkedBlockingQueue is in this category is that all this hadn't been figured out when the original collections framework was developed, but it was pretty clear by the time that the concurrent collections were being added. Doug Lea, who did much of the work on util.concurrent, has been quoted as saying,

Null sucks.

In the worst case, object wrappers or "poison objects" are always valid workarounds; Guava provides an Optional class which can serve that role in many cases, which is discussed extensively here on StackOverflow.

like image 123
Louis Wasserman Avatar answered Oct 16 '22 17:10

Louis Wasserman