...
This noncompliant example is comprised of an ArrayList
collection which is non-thread-safe by default. There is, however, a way around this drawback. Most thread-unsafe classes have a synchronized thread-safe version, synchronizedList
being a good substitute for ArrayList
. One pitfall described in the coming lines, remains to be addressed even when the particular Collection
offers thread-safety benefits.
Wiki Markup |
---|
The operations within a thethread's {{run()}} method are non-atomic. That is, it is possible thatfor the first thread willto operate on data that it does not expect. The superfluous data may be fed in by other threads whilewhilst the first thread hasis notstill finished processingexecuting. Conversely, sinceas the {{toArray()}} method produces a copy of the parameter, it is possible that the first thread operates on stale data \[[JavaThreads 04|AA. Java References#JavaThreads 04]\]. The code's output, consisting withof varying array lengths, signifies a race condition. Such omissions can be pernicious in methods that use complex formulas. |
...
Note that this advice applies to all Collection
classes including the thread-safe hash tables Hashtable
class. Enumerations of the objects of a Collection
and iterators also require explicit synchronization on the Collection
object or any single lock object.
Wiki Markup |
---|
Although expensive, {{CopyOnWriteArrayList}} and {{CopyOnWriteArraySet}} classes are sometimes used to create copies of the core {{Collection}} so that iterators do not fail with a runtime exception when some data in the {{Collection}} is modified. These however, suffer from the {{toArray}} dilemma (operating on stale data) described earlier in this rule. Consequently, their use is limited to boosting performance in code where the writes are fewer (or non-existent) as compared to the reads \[[JavaThreads 04|AA. Java References#JavaThreads 04]\]. In all other cases they must be avoided. |
...
Wiki Markup |
---|
Composition offers more benefits as compared thanto the previous solution, although at the cost of a slight performance penalty (refer to [OBJ01-J. Understand how a superclass can affect a subclass] for details on how to implement composition). This allows the {{CompositeCollection}} class to use its own intrinsic lock in a way that is completely independent of the lock of the underlying list class. This provides consistent locking even when the underlying list is not thread-safe or when it changes its locking policy. \[[Goetz 06|AA. Java References#Goetz 06]\] |
...