AtomicTest.java Source code

Java tutorial

Introduction

Here is the source code for AtomicTest.java

Source

/*
Java Threads, 3rd Edition
By Scott Oaks, Henry Wong
3rd Edition September 2004 
ISBN: 0-596-00782-5
    
*/

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

public class AtomicTest {
    static int nLoops;

    static int nThreads;

    public static void main(String[] args) {

        nLoops = 10000;
        nThreads = 1;
        doTest(new AtomicRunnable());
        doTest(new SyncRunnable());
        nLoops = Integer.parseInt(args[0]);
        nThreads = Integer.parseInt(args[1]);

        System.out.println("Starting atomic test");
        cleanGC();
        Timestamp atomicTS = new Timestamp();
        doTest(new AtomicRunnable());
        atomicTS.stop();
        System.out.println("Atomic took " + atomicTS);

        System.out.println("Starting sync test");
        cleanGC();
        Timestamp syncTS = new Timestamp();
        doTest(new SyncRunnable());
        syncTS.stop();
        System.out.println("Local sync took " + syncTS);

        double d = ((double) (syncTS.elapsedTime() - atomicTS.elapsedTime())) / (nLoops * nThreads);
        System.out.println("Atomic operation saves " + d + " " + syncTS.units() + " per call");
    }

    static void cleanGC() {
        System.gc();
        System.runFinalization();
        System.gc();
    }

    static class AtomicRunnable implements Runnable {
        AtomicInteger ai = new AtomicInteger(1);

        public void run() {
            for (int i = 0; i < nLoops; i++)
                ai.incrementAndGet();
        }
    }

    static class SyncRunnable implements Runnable {
        int testVar;

        synchronized void incrVar() {
            testVar++;
        }

        public void run() {
            for (int i = 0; i < nLoops; i++)
                incrVar();
        }
    }

    static void doTest(Runnable r) {
        Thread threads[] = new Thread[nThreads];
        for (int i = 0; i < nThreads; i++) {
            threads[i] = new Thread(r);
        }
        for (int i = 0; i < nThreads; i++) {
            threads[i].start();
        }
        for (int i = 0; i < nThreads; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException ie) {
            }
        }
    }
}

class Timestamp {

    private long startTime;

    private long stopTime;

    private boolean stopped = false;

    private TimeUnit ts;

    public Timestamp() {
        this(TimeUnit.NANOSECONDS);
    }

    public Timestamp(TimeUnit ts) {
        this.ts = ts;
        start();
    }

    public void start() {
        startTime = System.nanoTime();
        stopped = false;
    }

    public void stop() {
        stopTime = System.nanoTime();
        stopped = true;
    }

    public long elapsedTime() {
        if (!stopped)
            throw new IllegalStateException("Timestamp not stopped");
        return ts.convert(stopTime - startTime, TimeUnit.NANOSECONDS);
    }

    public String toString() {
        try {
            return elapsedTime() + " " + ts;
        } catch (IllegalStateException ise) {
            return "Timestamp (not stopped)";
        }
    }

    public String units() {
        return ts.toString();
    }
}