threads
Thread performance on Atomic type
With this example we are going to demonstrate how to check a thread performance on atomic type. We are testing two runnable objects, one that uses an AtomicInteger and another one that uses a synchronized
method. The example is described in short:
- We have created a class,
AtomicRunnable
that implements the Runnable, uses an AtomicInteger and in its overridenrun()
method increases it, using theincreamentAndGet()
API method of AtomicInteger. - We have also created a class,
SyncRunnable
that implements the Runnable and in its overridedrun()
method uses its methodincrVar()
in a synchronized keyword in order to increase the value of an int variable. - We have a static method,
performanceTest(Runnable runnable)
that creates new threads with the given runnables and calls theirstart()
method to begin their execution and theirjoin()
method that waits for the threads to die. - We have also created a class,
Timestamp
, that in itsstart()
andstop()
methods gets theSystem.nanoTime()
and in itselapsedTime()
method converts the subtraction between start and end time and usesconvert(long sourceDuration, TimeUnit sourceUnit)
method of TimeUnit to convert time duration to the given TimeUnit. - We call the
performanceTest(Runnable runnable)
method for the two Runnables created above and we use the Timestamp class to count the time both runnables need to execute.
Let’s take a look at the code snippet that follows:
package com.javacodegeeks.snippets.core; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class Performance { static int loops; static int threads; public static void main(String[] args) { loops = 1000; threads = 10; performanceTest(new AtomicRunnable()); performanceTest(new SyncRunnable()); System.out.println("Atomic test"); cleanAll(); Timestamp timeStamp = new Timestamp(); performanceTest(new AtomicRunnable()); timeStamp.stop(); System.out.println("Atomic took " + timeStamp); System.out.println("Sync test"); cleanAll(); Timestamp timeStampSync = new Timestamp(); performanceTest(new SyncRunnable()); timeStampSync.stop(); System.out.println("Sync took " + timeStampSync); double gained = ((double) (timeStampSync.elapsedTime() - timeStamp.elapsedTime())) / (loops * threads); System.out.println("Atomic (unsynch) operation saves " + gained + " " + timeStampSync.units() + " per call"); } static void cleanAll() { System.gc(); System.runFinalization(); System.gc(); } static class AtomicRunnable implements Runnable { AtomicInteger atomicInt = new AtomicInteger(1); @Override public void run() { for (int i = 0; i < loops; i++) { atomicInt.incrementAndGet(); } } } static class SyncRunnable implements Runnable { int i; synchronized void incrVar() { i++; } @Override public void run() { for (int i = 0; i < loops; i++) { incrVar(); } } } static void performanceTest(Runnable runnable) { Thread threads[] = new Thread[Performance.threads]; for (int i = 0; i < Performance.threads; i++) { threads[i] = new Thread(runnable); } for (int i = 0; i < Performance.threads; i++) { threads[i].start(); } for (int i = 0; i < Performance.threads; i++) { try { threads[i].join(); } catch (InterruptedException ie) { } } } } class Timestamp { private long start; private long end; private boolean stopped = false; private TimeUnit unit; public Timestamp() { this(TimeUnit.NANOSECONDS); } public Timestamp(TimeUnit unit) { this.unit = unit; start(); } public void start() { start = System.nanoTime(); stopped = false; } public void stop() { end = System.nanoTime(); stopped = true; } public long elapsedTime() { if (!stopped) { throw new IllegalStateException("Timestamp didn't stop"); } return unit.convert(end - start, TimeUnit.NANOSECONDS); } @Override public String toString() { try { return elapsedTime() + " " + unit; } catch (IllegalStateException ise) { return "Timestamp didn't stop"; } } public String units() { return unit.toString(); } }
Output:
Atomic test
Atomic took 1110387 NANOSECONDS
Sync test
Sync took 1965840 NANOSECONDS
Atomic (unsynch) operation saves 85.5453 NANOSECONDS per call
This was an example of how to check a thread performance on atomic type in Java.