Parag
Parag

Reputation: 12453

Why was thread safety sacrificed in new Collection library in Java?

Were there reasons other than performance to sacrifice thread safety in the new Collections library in Java ?

Upvotes: 3

Views: 124

Answers (3)

mikera
mikera

Reputation: 106401

Performance is the main reason.

However, there is also an important philosophical/design reason: you cannot achieve full thread safety just by making individual collection classes thread safe.

Safe concurrent code typically requires synchronisation at a different level, for example:

  • At a higher level - locking two collections simultaneously so you can remove an element from one and add it to the other)
  • At a lower level - locking individual rows of items in a concurrent data table

So in a way, making collection classes synchronised would be a fairly arbitrary decision that wouldn't be suitable for many (if not most) circumstances. It's therefore a better option to make the collections unsafe and let the user decide their concurrency strategy (whether or not it is needed, appropriate level of granularity, approach to transactions etc.)

Apart from that, the other option is to take the approach pioneered by Clojure and use immutable persistent collection classes so you don't have to worry about locks or thread safety at all. But that requires a slightly more wholesale rethinking of your approach to state....

Upvotes: 6

Thilo
Thilo

Reputation: 262850

Why is performance not good enough of a reason?

Mandatory thread "safety" (probably incomplete for most cases anyway -- for example there was no putIfAbsent) was removed, so you don't have to pay the cost when you don't need it, but still have the option to make things thread-safe yourself (and with a granularity of your choosing) when you do.

I guess the realization was that there is no way to bake in automatic thread-safety that does not require the programmer to think about it, can be used in all situations, works reliably and adds no significant overhead.

Also note that the "even newer" concurrency utils package brings a couple of new thread-safe collection implementations that serve very specific purposes. Again, you need different tools for different tasks and the old collection classes provided a very poor middle-ground that was not really suited for most applications.

Upvotes: 5

JB Nizet
JB Nizet

Reputation: 692231

Yes, there is another reason. Making every method of a collection synchronized makes the collection thread-safe, but

  • there are faster solutions (like the concurrent collections)
  • it's not enough anyway, because you often have to implement check-then-act operations (like checking if an element is present, and add it if not), or iterations, that need external synchronization anyway

Moreover, thread-safety wasn't sacrificed at all, since you just need to wrap your ArrayList (for example) in a synchronized collection proxy to have the same synchronization guarantees as the old, synchronized by default Vector:

List<String> list = Collections.synchronizedList(new ArrayList<String>());

So you get the best of both: fast collections when you don't need synchronization (99% of the cases), and synchronized collections when you want them.

Upvotes: 6

Related Questions