...
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.
...