...
Enumerations of objects of a Collection
and iterators also require explicit synchronization on the Collection
object (client-side locking) or any single an internal private lock object.
...
This noncompliant code example uses two thread-safe AtomicReference
objects that wrap one BigInteger
object , each.
Code Block | ||
---|---|---|
| ||
final class Adder { private final AtomicReference<BigInteger> first; private final AtomicReference<BigInteger> second; public Adder(BigInteger f, BigInteger s) { first = new AtomicReference<BigInteger>(f); second = new AtomicReference<BigInteger>(s); } public void update(BigInteger f, BigInteger s) { // Unsafe first.set(f); second.set(s); } public BigInteger add() { // Unsafe return first.get().add(second.get()); } } |
An AtomicReference
is an object reference that can be updated atomically. Operations that use these two atomic references independently, are guaranteed to be atomic, however, if an operation involves using both together, thread-safety issues arise. In this noncompliant code example, one thread may call update()
while a second thread may call add()
. This might cause the add()
method to add the new value of first
to the old value of second
, yielding an erroneous result.
...
Code Block | ||
---|---|---|
| ||
final class IPHolder { private final List<InetAddress> ips = Collections.synchronizedList(new ArrayList<InetAddress>()); public void addIPAddress(InetAddress address) { // Validate address ips.add(address); } public void addAndPrintIP(InetAddress address) throws UnknownHostException { addIPAddress(address); InetAddress[] ia = (InetAddress[]) ips.toArray(new InetAddress[0]); System.out.println("Number of IPs: " + ia.length); } } |
...
Code Block | ||
---|---|---|
| ||
final class IPHolder { private final List<InetAddress> ips = Collections.synchronizedList(new ArrayList<InetAddress>()); public void addIPAddress(InetAddress address) { synchronized (ips) { // Validate ips.add(address); } } public void addAndPrintIP(InetAddress address) throws UnknownHostException { synchronized (ips) { addIPAddress(address); InetAddress[] ia = (InetAddress[]) ips.toArray(new InetAddress[0]); System.out.println("Number of IPs: " + ia.length); } } } |
...
The integer overflow check that should be used before incrementing has been omitted for brevity; . To prevent overflow, the caller must ensure that the {increment()
}} method is called no more than Integer.MAX_VALUE
times for any key to prevent overflow. Refer to INT00-J. Perform explicit range checking to ensure integer operations do not overflow for more information.
...