Java concurrency: weird output

I’m fooling around with Java threads and I wrote this little program that creates several threads and runs them. In each thread a value is incremented multiple times. I used ThreadLocal class so that there’s no contention for resources.

Source:

class MyValueHolder {

    public static ThreadLocal<Integer> value = new ThreadLocal<Integer>()
    {
        protected Integer initialValue() {
            return 0;
        }
    };

    public static void increment() {
        value.set(value.get() + 1);
    }

    public static Integer get() {
        return value.get();
    }
}

class MyTask implements Runnable {

    public static int counter;

    public MyTask() {
        counter++;
    }

    public void run() {

        for(int i = 0; i < 100; i++) {
            MyValueHolder.increment();
        }
        System.out.println("MyTask " + counter + ", Value " + MyValueHolder.get());
    }
}

public class Main {

    public static void main(String[] args) {

        ExecutorService es = Executors.newCachedThreadPool();

        for(int i = 0; i < 5; i++) {

            es.execute(new MyTask());
        }

        es.shutdownNow();
    }
}

After completion the output is most of the time this:

MyTask 5, Value 100
MyTask 5, Value 100
MyTask 5, Value 100
MyTask 5, Value 100
MyTask 5, Value 100

Which is what I’d expect to see.

However, sometimes I get something like this:

MyTask 2, Value 100
MyTask 4, Value 200
MyTask 5, Value 300
MyTask 5, Value 100
MyTask 5, Value 100

Now this is confusing. Why do the values differ even though each task does absolutely the same thing?

Answer

The CachedThreadPoolExecutor reuses threads if a Runnable finishes before you have added all Runnables. If this happens the ThreadLocal of that thread will also be reused.

Leave a Reply

Your email address will not be published. Required fields are marked *