AtomicInteger

For Java 11 Certification Exam Practice Questions, refer http://talks.skilltoz.com/java-11-certification-exam-questions/

Coverage in Java 11 Certification Exam

The Java 11 Certification exam objective covers java.util.concurrent API. The classes in the java.util.concurrent.atomic package are useful in multithreaded applications to safely access individual variables without locking. Some of these classes are AtomicInteger, AtomicLong, AtomicBoolean, and AtomicReference. We shall explore what you need to know about AtomicInteger to clear the Java 11 certification exam.

What is AtomicInteger

The AtomicInteger class can be used as a replacement for Integer, if we need to modify an integer concurrently in a thread-safe way without synchronizing the access to the variable.

Why we need it

Let us consider an example.

public class Counter {
   private int count;
   public void increment() {
	count++; // line x
   }
   public int getValue() {
     return count;
   }
}

In the above example, the operation in line x is not an atomic operation and hence can produce unpredictable results on concurrent access. We can make this class thread-safe either through synchronization/locking or by replacing int with AtomicInteger. So how do we create and use an AtomicInteger?

Creating an AtomicInteger

The AtomicInteger class can be instantiated with one of the two overloaded constructors.

AtomicInteger() – Creates a new AtomicInteger with initial value 0.
AtomicInteger​(int initialValue) – Creates a new AtomicInteger with the given initial value.

Getting the value

You can use the get() method to read the value of an AtomicInteger as an int.

AtomicInteger ai = new AtomicInteger(100);
int val = ai.get();
// val is now 100

Setting the value

You can use the set() method to set an int as the value of an AtomicInteger.

AtomicInteger ai = new AtomicInteger();	
ai.set(10); // The value of ai is set to 10

Getting and Setting Atomically

What if you want to atomically set the value to a new one and return the old value? You can use the getAndSet() method.

AtomicInteger ai = new AtomicInteger();	
int oldVal = ai.getAndSet(20);
int newVal = ai.get();
System.out.println(oldVal + " changed to "+ newVal); 
// The output is: 0 changed to 20

Comparing and Setting Atomically

Another useful atomic operation available is compareAndSet(). This method atomically sets the value to newValue if the current value == expectedValue.

AtomicInteger ai = new AtomicInteger(10);	
int expectedValue = 10;
int newValue      = 100;
ai.compareAndSet(expectedValue, newValue);
int val = ai.get(); // val is now 100

In the above example, the value of ai is 10 which is the same as the expected value. Hence, the new value is set to 100.

Incrementing and Decrementing Atomically

If we want to add 1 to a primitive integer i, we can use the increment operator (++i is a prefix operator that returns the value after it is incremented, while i++ is a postfix operator that returns the value before it is incremented). In the case of AtomicInteger, we can use incrementAndGet() and getAndIncrement() methods to increment by 1.

AtomicInteger ai = new AtomicInteger();
System.out.println(ai.getAndIncrement());  // Prints 0
System.out.println(ai.incrementAndGet());  // Prints 2

As you can see in the above example, incrementAndGet() is a prefix method like ++i while getAndIncrement() is a postfix method like i++.

Similar to the incrementing operations we saw now, the operations to decrement the value by 1 are as follows.

decrementAndGet() – It subtracts 1 from the AtomicInteger value and returns the value.
getAndDecrement() – This also subtracts 1 from the AtomicInteger value but returns the value the AtomicInteger had before decrementing.

Adding Atomically

There are also operations that add a value to the AtomicInteger and get its value returned. These methods are:

addAndGet() -This method adds the given number to the AtomicInteger and returns the new value.

getAndAdd() – This method also adds a number to the AtomicInteger but returns the value the AtomicInteger had before the value was added.

Here is an example.

AtomicInteger ai = new AtomicInteger(10);
System.out.println(ai.getAndAdd(10)); // Prints 10
System.out.println(ai.addAndGet(10)); // Prints 30

Summary

The classes in the java.util.concurrent.atomic package such as AtomicInteger are conceptually the same as the primitive classes, but support atomic operations. Autoboxing is not supported for these classes. An AtomicInteger is used in applications such as atomically incremented counters.

Leave a Reply

Your email address will not be published. Required fields are marked *