Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This noncompliant code example attempts to resolve the problem by declaring itemsInInventory as volatile.

Code Block
bgColor#FFcccc
private volatile int itemsInInventory = 100;

public final int removeItem() {
  if (itemsInInventory > 0) {
    return itemsInInventory--;  // Returns new count of items in inventory
  } 
  return -1; // Error code  
}

public final int returnItem() {
  if (itemsInInventory == Integer.MAX_VALUE) { // Check for integer overflow
    return -1; // Error Code
  } else {
    return itemsInInventory++;
  }
}

Volatile variables are unsuitable when more than one read/write operation needs to be atomic. The use of a volatile variable in this noncompliant code example guarantees that once itemsInInventory has been updated, the new value is visible to all threads that read the field. However, because the post decrement operator is nonatomic, even when volatile is used, the interleaving described in the previous noncompliant code example is still possible.

Similarly, the increment composite operation in the returnItem() method does not perform the increment operation atomicallyis non-atomic.

Compliant Solution (java.util.concurrent.atomic classes)

The java.util.concurrent utilities can be used to atomically manipulate a shared variable. This compliant solution uses a {java.util.concurrent.atomic.AtomicInteger}} variable which allows certain composite operations to be performed atomically.

...

Wiki Markup
The {{compareAndSet()}} method takes two arguments, the expected value of a variable when the method is invoked and the updated value. This compliant solution uses this method to atomically set the value of {{itemsInInventory}} to the updated value if and only if the current value equals the expected value. \[[API 06|AA. Java References#API 06]\].  The {{for}} loop guarantees the same behavior of the original function, namely that the function succeeds in decrementing {{itemsInInventory}} or an error is returned.

The returnItem() method can be fixed by using the java.util.concurrent.atomic.AtomicInteger.getAndIncrement() method.

...