Java & J2EE Page 4 - Taming Tiger: Concurrent Collections |
The new java.util.concurrent.ConcurrentMap interface and the ConcurrentHashMap implementation let you add an element to a map only if the key isn't present and remove an element from a map only if the key is present and mapped to a specific value. For adding to the map, there's the new putIfAbsent() method. The method accepts the key and value to add to the ConcurrentMap implementation, like the normal put() method, but will only add the key to the map if the map doesn't contain the key. If the map already contains the key, the existing value for the key is preserved. The putIfAbsent() method is atomic. Without calling this atomic operation, the code in Listing 4 would need to be called from an appropriately synchronized block: Listing 4. Equivalent putIfAbsent() code
Listing 5. Equivalent remove() code if (map.get(key).equals(value)) { Using CopyOnWriteArrayList and CopyOnWriteArraySet The copy-on-write pattern is described best in Doug Lea's Concurrent Programming in Java book, Chapter 2, Section 2.4.4 (see Resources list). Essentially, the pattern states that to maintain a consistent snapshot of an object, you rely on immutability to eliminate the need for synchronization when you need to coordinate readings of separate but related attributes. For collections, that means that if you have a lot of reads (that is, get()) and iterations, you don't have to synchronize the operations to worry about the occasional write (that is, add()) call. For the new CopyOnWriteArrayList and CopyOnWriteArraySet classes, all mutable operations make a copy of the backing array first, make the change to the copy, and then replace the copy. This behavior guarantees that ConcurrentModificationException will never be thrown while iterating over a collection that is changing underneath itself. Iterating through the collection will complete with the original collection, while the updated collection will be available for future operations. These new collections, CopyOnWriteArrayList and CopyOnWriteArraySet, work best when the read operations typically far outweigh the write operations. One example frequently mentioned is for the use of listener lists. Having said that, the Swing components have not been modified to use the new collections. Instead, they continue to use a javax.swing.event.EventListenerList for the maintenance of their lists of listeners. As Listing 6 demonstrates, the use of the collection is identical to their non-copy-on-write alternative. Just create the collection and add or remove elements from it. Even as objects get added to the collection, the original Iterator can proceed, working through the items in the original collection. Listing 6. Demonstrating a copy-on-write collection import java.util.*; public class CopyOnWrite { The sample program creates both a CopyOnWriteArrayList and ArrayList instance from the command line arguments. After getting an Iterator from each, an element is added to each. The CopyOnWriteArrayList iteration is able to proceed without exception while the ArrayList iteration stops immediately with a ConcurrentModificationException problem, because the original collection changed after getting the iterator. As long as this is the behavior you want, like for notifying all of the elements in the original set of event listeners, you're better off using the copy-on-write collections. If not, stick with the originals, and be sure to deal with the exception if and when it happens. Conclusion There are many big additions to the Tiger release of the J2SE platform. In addition to the language-level changes like generics support, this one library is probably the biggest addition as far as what will be used by the widest audiences. Not to belittle other packages added to the platform, like the Java Management Extensions (JMX), but most other big library enhancements are meant for narrower groups of developers. This library isn't. In addition to the other concurrency utilities for locking and atomic operations, expect to use these classes regularly. Learn them early and take advantage of what they offer.
blog comments powered by Disqus |