Java Multithreading - Threadsafe Counter

BrotherBarnabas picture BrotherBarnabas · Apr 26, 2015 · Viewed 36.4k times · Source

I'm starting off with a very simple example in multithreading. I'm trying to make a threadsafe counter. I want to create two threads that increment the counter intermittently to reach 1000. Code below:

public class ThreadsExample implements Runnable {
     static int counter = 1; // a global counter

     public ThreadsExample() {
     }

     static synchronized void incrementCounter() {
          System.out.println(Thread.currentThread().getName() + ": " + counter);
          counter++;
     }

     @Override
     public void run() {
          while(counter<1000){
               incrementCounter();
          }
     }

     public static void main(String[] args) {
          ThreadsExample te = new ThreadsExample();
          Thread thread1 = new Thread(te);
          Thread thread2 = new Thread(te);

          thread1.start();
          thread2.start();          
     }
}

From what I can tell, the while loop right now means that only the first thread has access to the counter until it reaches 1000. Output:

Thread-0: 1
.
.
.
Thread-0: 999
Thread-1: 1000

How do I fix that? How can I get the threads to share the counter?

Answer

Bert Peters picture Bert Peters · Apr 26, 2015

You could use the AtomicInteger. It is a class that can be incremented atomically, so two seperate threads calling its increment method do not interleave.

public class ThreadsExample implements Runnable {
     static AtomicInteger counter = new AtomicInteger(1); // a global counter

     public ThreadsExample() {
     }

     static void incrementCounter() {
          System.out.println(Thread.currentThread().getName() + ": " + counter.getAndIncrement());
     }

     @Override
     public void run() {
          while(counter.get() < 1000){
               incrementCounter();
          }
     }

     public static void main(String[] args) {
          ThreadsExample te = new ThreadsExample();
          Thread thread1 = new Thread(te);
          Thread thread2 = new Thread(te);

          thread1.start();
          thread2.start();          
     }
}