Reputation: 12453
Were there reasons other than performance to sacrifice thread safety in the new Collections library in Java ?
Upvotes: 3
Views: 124
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:
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
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
Reputation: 692231
Yes, there is another reason. Making every method of a collection synchronized makes the collection thread-safe, but
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