Choosing the Best Concurrency List in Java

Choosing the best concurrency list in Java

had better be List

The only List implementation in java.util.concurrent is CopyOnWriteArrayList. There's also the option of a synchronized list as Travis Webb mentions.

That said, are you sure you need it to be a List? There are a lot more options for concurrent Queues and Maps (and you can make Sets from Maps), and those structures tend to make the most sense for many of the types of things you want to do with a shared data structure.

For queues, you have a huge number of options and which is most appropriate depends on how you need to use it:

  • ConcurrentLinkedQueue
  • ArrayBlockingQueue
  • LinkedBlockingDeque
  • LinkedBlockingQueue
  • PriorityBlockingQueue
  • SynchronousQueue
  • DelayQueue

Is there a concurrent List in Java's JDK?

There is a concurrent list implementation in java.util.concurrent. CopyOnWriteArrayList in particular.

Selection of the best concurrency approach

There is no framework more suitable for this task than good old threads. The problem with threads is that they are taught with synchronized keyword from the start, while in most cases, it can be avoided. Use BlockingQueues whenever possible, and your program would be clean and understandable.

The structure of your program can be as follows:

T1->Q1->TP1->Q2->T2->Q3->TP2->Q4->T3

Thread T1 (it can be the main thread) splits input list into small queries and puts them into queue Q1.
Thread Pool TP1 is just a number of threads, each of which takes queries from Q1, access the service 1 and puts the result into queue Q2.
Thread T2 takes the responses from Q2, filters them, packs in batches of 10 and puts into Q3.
Thread Pool TP2 sends queries from Q3 to the 2nd service and puts results into Q4.
Thread T3 forms the final list.

Best way to control concurrent access to Java collections

Vector and the List returned by Collections.synchronizedList() are morally the same thing. I would consider Vector to be effectively (but not actually) deprecated and always prefer a synchronized List instead. The one exception would be old APIs (particularly ones in the JDK) that require a Vector.

Using a naked ArrayList and synchronizing independently gives you the opportunity to more precisely tune your synchronization (either by including additional actions in the mutually exclusive block or by putting together multiple calls to the List in one atomic action). The down side is that it is possible to write code that accesses the naked ArrayList outside synchronization, which is broken.

Another option you might want to consider is a CopyOnWriteArrayList, which will give you thread safety as in Vector and synchronized ArrayList but also iterators that will not throw ConcurrentModificationException as they are working off of a non-live snapshot of the data.

You might find some of these recent blogs on these topics interesting:

  • Java Concurrency Bugs #3 - atomic + atomic != atomic
  • Java Concurrency Bugs #4: ConcurrentModificationException
  • CopyOnWriteArrayList concurrency fun

Which concurrent collection to use?

Yes, ConcurrentHashMap is appropriate for this. Use the user name as key type (K) and the associated user information ("some strings and ints") as value type (V) in the map. Use put to add new key-value pairs, remove to remove key-value pairs, and entrySet to get all key-value pairs in the container (if that is what you meant by "reading all elements from the collection").

How do I make my ArrayList Thread-Safe? Another approach to problem in Java?

Use Collections.synchronizedList().

Ex:

Collections.synchronizedList(new ArrayList<YourClassNameHere>())


Related Topics



Leave a reply



Submit