javamultithreadingconcurrencysynchronization

Are LinkedBlockingQueue's insert and remove methods thread safe?


I'm using LinkedBlockingQueue between two different threads. One thread adds data via add, while the other thread receives data via take.

My question is, do I need to synchronize access to add and take. Is LinkedBlockingQueue's insert and remove methods thread safe?


Solution

  • Yes. From the docs:

    "BlockingQueue implementations are thread-safe. All queuing methods achieve their effects atomically using internal locks or other forms of concurrency control. However, the bulk Collection operations addAll, containsAll, retainAll and removeAll are not necessarily performed atomically unless specified otherwise in an implementation. So it is possible, for example, for addAll(c) to fail (throwing an exception) after adding only some of the elements in c."

    EDIT: The addAll behavior is not a multithreading-specific issue, because a single-threaded scenario can have exactly the same problem.

    In a single-threaded app, create an ArrayList list with 9 non-null elements and one null element at the end.

    Call queue.addAll(list);

    Assuming it adds the elements in sequential order (I don't believe this is guaranteed but it likely will), it will add the first 9, then throw an exception. (BlockingQueue does not allow null elements.) The 9 will still get added to the queue.

    1. Asking for addAll to be atomic is asking a lot, whether the collection is thread-safe or not. It requires snapshoting the whole collection then rolling back. Yes, it could be implemented for many collections (though for some it would be complex), but I wouldn't assume any collection (thread-safe or not) did.

    Bottom line: Collections are complex and their guarantees vary. It's important to consult the documentation. Thread-safety is just one concern of many.