andrew-g-za
andrew-g-za

Reputation: 987

Concurrent Thread-safe AtomicInteger

I've read through the API documentation of the java.util.concurrent package, but have obviously misunderstood something. The overview says

A small toolkit of classes that support lock-free thread-safe programming on single variables.

However, a small test application shows that the AtomicInteger class does not provide thread-safety, at least when it is shared across threads (I accept that the getAndSet / increment methods themselves are at least atomic)

Test:

import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntTest
{
    public static void main(String[] args) throws InterruptedException
    {
        AtomicInteger atomicInt = new AtomicInteger(0);
        WorkerThread w1 = new WorkerThread(atomicInt);
        WorkerThread w2 = new WorkerThread(atomicInt);
        w1.start();
        w2.start();
        w2.join(); // <-- As pointed out by StuartLC and BarrySW19, this should be w1.join(). This typo allows the program to produce variable results because it does not correctly wait for *both* threads to finish before outputting a result.
        w2.join();
        System.out.println("Final value: " + atomicInt.get());
    }

    public static class WorkerThread extends Thread
    {
        private AtomicInteger atomicInt = null;
        private Random random = new Random();

        public WorkerThread(AtomicInteger atomicInt)
        {
            this.atomicInt = atomicInt;
        }

        @Override
        public void run()
        {
            for (int i = 0; i < 500; i++)
            {
                this.atomicInt.incrementAndGet();
                try
                {
                    Thread.sleep(this.random.nextInt(50));
                }
                catch(InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

When I run this class, I consistently get results ranging from around 950 to 1000, when I would expect to always see exactly 1000.

Can you explain why do I not get consistent results when two threads access this shared AtomicInteger variable? Have I misunderstood the thread-safety guarantee?

Upvotes: 0

Views: 674

Answers (1)

BarrySW19
BarrySW19

Reputation: 3809

Looks like a simple cut&paste error - you are joining to thread "w2" twice and never to "w1". At present, you would expect the thread "w1" to still be running half the time when you print the 'final' value.

Upvotes: 1

Related Questions