java.util.concurrent.atomic: How to use Java Atomic Classes? AtomicInteger

It has been some time since the release of Java 5. It introduced a number of improvements in terms of classes to handle concurrency concerns. Today I will cruising thru the java.util.concurrent.atomic package and looking at the package’s relevance in tackling real-life issues.

Let’s get started with the most basic requirements. Assume that you have a web site that maintains the number of users accessing a page. The counter information is not persisted beyond the web site up time. Therefore, we just need a counter to maintain a count of the number of users accessing a page. This can be achieved by creating a counter which is incremented on every page access. To ensure precise measurement, the counter needs to be incremented by a single thread and no other thread should access the counter variable. In pre Java 5 days, we would have to control access to the counter variable using a synchronized block. Here’s the sample code to do it:

Let’s get started with the most basic requirements. Assume that you have a web site that maintains the number of users accessing a page. The counter information is not persisted beyond the web site up time. Therefore, we just need a counter to maintain a count of the number of users accessing a page. This can be achieved by creating a counter which is incremented on every page access. To ensure precise measurement, the counter needs to be incremented by a single thread and no other thread should access the counter variable. In pre Java 5 days, we would have to control access to the counter variable using a synchronized block. Here’s the sample code to do it:

class Counter {

	private int count = 0;

	Counter () {

	}

	synchronized void increment() {
		count++;
	}

	int getCount() {
		return count;
	}
}

The synchronized is an all or nothing block. Java 5 provides an improved solution to handle the problem instead use the java.util.concurrent.atomic.AtomicInteger. This class implements the behavior as expected from Counter and in a more efficient manner. I have created the following test codes to verify the results:

public class CounterTest {

	public static void main(String[] args) {

		Counter counter = new Counter();

		for(int i=0; i< 1600; i++) {
			//This loop to get rid of any hotspot optimizations
			counter.increment();
		}

		long startTime = System.nanoTime();

		for(int i=0; i< 150000; i++) {
			counter.increment();
		}

		long endTime = System.nanoTime();
		double processingTime = (endTime - startTime)/Math.pow(10, 6);

		System.out.println("Processing Time (msec): " + processingTime + " Count: " + counter.getCount());

	}

}

public class AtomicIntegerTest {

	public static void main(String[] args) {
		AtomicInteger counter = new AtomicInteger(0);

		for(int i=0; i< 1600; i++) {
			//This loop to get rid of any hotspot optimizations
			counter.incrementAndGet();
		}

		long startTime = System.nanoTime();

		for(int i=0; i< 150000; i++) {
			counter.incrementAndGet();
		}

		long endTime = System.nanoTime();
		double processingTime = (endTime - startTime)/Math.pow(10, 6);

		System.out.println("Processing Time (msec): " + processingTime + " Count: " + counter.intValue());

	}

}
Running CounterTest displays the following:
Processing Time (msec): 18.196106 Count: 151600
Running AtomicIntegerTest displays the following:
Processing Time (msec): 11.212189 Count: 151600
There is a considerable improvement in performance. OK the next question is whether the counter is incrementing properly. Here’s how I tested it:
public class ConcurrencyTest {

	public static void main(String[] args) {
		AtomicInteger counter = new AtomicInteger(0);

		for(int i=0; i<100; i++) {
			Runnable runnable = new WorkerThread(counter);
			Thread t = new Thread(runnable);
			t.start();
		}

	}

}

class WorkerThread implements Runnable {

	AtomicInteger count = null;

	WorkerThread(AtomicInteger counter) {
		this.count = counter;
	}

	public void run() {
		int value = this.count.incrementAndGet();
		System.out.println(value);
	}
}
The output of the ConcurrencyTest run is a sequential value starting from 1 and ending at 100.

There are AtomicIntegerArray and AtomicLongArray classes.Apparently there is no AtomicFloat or AtomicDouble. The reason is explained in a foot note in the package summary.

You can also hold floats using Float.floatToIntBits and Float.intBitstoFloat conversions, and doubles using Double.doubleToLongBits and Double.longBitsToDouble conversions.

Advertisements

5 thoughts on “java.util.concurrent.atomic: How to use Java Atomic Classes? AtomicInteger

  1. Unquestionably believe that which you said. Your favorite reason appeared to be on the
    internet the simplest thing to be aware of. I say to
    you, I certainly get irked while people think about worries that they plainly
    don’t know about. You managed to hit the nail upon the top as well as defined out the whole thing without having side-effects
    , people can take a signal. Will probably be back to get more.

    Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s