A Simple Example With Lock..

.. AtomicInteger and synchronized block!

This is my project structure:

Implementations

package biz.tugay.sandbox.counter;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 14/07/2017
 */
public interface ThreadSafeCounter {
    void increment();
    void reset();
    int value();
}
package biz.tugay.sandbox.counter;
 
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 14/07/2017
 */
public class CounterWithLockImpl implements ThreadSafeCounter {
 
    private int count;
 
    private final Lock lock = new ReentrantLock();
 
    @Override
    public void increment() {
        lock.lock();
        count++;
        lock.unlock();
    }
 
    @Override
    public int value() {
        return count;
    }
 
    @Override
    public void reset() {
        count = 0;
    }
}
package biz.tugay.sandbox.counter;
 
import java.util.concurrent.atomic.AtomicInteger;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 14/07/2017
 */
public final class CounterAtomicImpl implements ThreadSafeCounter {
 
    private final AtomicInteger counter = new AtomicInteger();
 
    @Override
    public void increment() {
        counter.getAndIncrement();
    }
 
    @Override
    public void reset() {
        counter.set(0);
    }
 
    @Override
    public int value() {
        return counter.intValue();
    }
}
package biz.tugay.sandbox.counter;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 14/07/2017
 */
public class CounterSynchronizedImpl implements ThreadSafeCounter {
 
    private int counter;
 
    @Override
    public synchronized void increment() {
        counter++;
    }
 
    @Override
    public void reset() {
        counter = 0;
    }
 
    @Override
    public int value() {
        return counter;
    }
}
package biz.tugay.sandbox.incrementer;
 
import biz.tugay.sandbox.counter.ThreadSafeCounter;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 14/07/2017
 */
public class RunnableCounterIncrementerImpl implements Runnable {
 
    private final ThreadSafeCounter threadSafeCounter;
    private final int loopCount;
 
    public RunnableCounterIncrementerImpl(final ThreadSafeCounter threadSafeCounter, final int loopCount) {
        this.threadSafeCounter = threadSafeCounter;
        this.loopCount = loopCount;
    }
 
    @Override
    public void run() {
        for (int i = 0; i < loopCount; i++) {
            threadSafeCounter.increment();
        }
    }
}
package biz.tugay.sandbox;
 
import biz.tugay.sandbox.counter.CounterSynchronizedImpl;
import biz.tugay.sandbox.counter.ThreadSafeCounter;
import biz.tugay.sandbox.incrementer.RunnableCounterIncrementerImpl;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 14/07/2017
 */
public class App {
 
    private final static int loopCount = 10000000;
 
    public static void main(String[] args) {
        final ThreadSafeCounter threadSafeCounter;
 
        threadSafeCounter = new CounterSynchronizedImpl();
        // threadSafeCounter = new CounterAtomicImpl();
        // threadSafeCounter = new CounterWithLockImpl();
 
        // Warm Up..
        for (int i = 0; i < 2; i++) {
            countUsingCounter(threadSafeCounter);
            threadSafeCounter.reset();
        }
 
        final long start = System.currentTimeMillis();
        countUsingCounter(threadSafeCounter);
        final long end = System.currentTimeMillis();
 
        System.out.println("Counter took: " + (end - start) + " ms.");
    }
 
    private static void countUsingCounter(final ThreadSafeCounter threadSafeCounter) {
        final RunnableCounterIncrementerImpl runnableCounterIncrementer 
                = new RunnableCounterIncrementerImpl(threadSafeCounter, loopCount);
 
        final Thread counter_01_t = new Thread(runnableCounterIncrementer);
        final Thread counter_02_t = new Thread(runnableCounterIncrementer);
 
        counter_01_t.start();
        counter_02_t.start();
 
        try {
            counter_01_t.join();
            counter_02_t.join();
        } catch (InterruptedException ignored) {
            // do nothing..
        }
 
        assert threadSafeCounter.value() == (loopCount * 2) 
                : "ThreadSafeCounter is not thread safe!";
    }
}