Archive

Archive for November, 2009

Series about Java Concurrency – Pt. 1

November 27, 2009 4 comments

As this is one of the things I’m currently occupied with, I’ve decided to start my blog with a series about Java-Concurrency. It’s going to consist of a series of thread related puzzles and their solutions. This approach is heavily inspired by the very interesting book Java Puzzlers which I strongly recommend to everyone who is doing serious Java programming. The solutions, together with detailed explanations, will usually appear a few days after the puzzles. You are strongly encouraged to analyze the source code carefully and predict its behavior without using a compiler. Only then you should run the program to see if your assumptions where true. Also note that because we are talking about threads, the results you get may vary depending on your hardware, operating system, JVM and system load.

So, what does the following program print (execute it at least 10 times)? Can you explain what is happening? If you think that you know what is going on, feel free to post it!

package at.lnet.puzzle;

import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;

public class AllTheSameButDifferent
{
    private static EntityManager entityManager;
    
    private static class EntityManager
    {
        private final Set<Integer> data = Collections.synchronizedSet(new TreeSet<Integer>());
        
        public void persist(final int value)
        {
            data.add(value);
        }
        
        public Set<Integer> getData()
        {
            return Collections.unmodifiableSet(data);
        }
    }
    
    private static class Action implements Runnable
    {
        private final int data;
        
        public Action(final int data)
        {
            this.data = data;
        }
        
        @Override
        public void run()
        {
            synchronized(this)
            {
                if(entityManager == null)
                    entityManager = new EntityManager();
            }
            entityManager.persist(data);
        }
    }
    
    public static void main(final String[] args) throws InterruptedException
    {
        final int NTHREADS = 4;
        Thread[] threads = new Thread[NTHREADS];
        
        for(int i = 0; i != NTHREADS; ++i)
            threads[i] = new Thread(new Action(i));
        for(int i = 0; i != NTHREADS; ++i)
            threads[i].start();
        for(int i = 0; i != NTHREADS; ++i)
            threads[i].join();
        
        System.out.println(entityManager.getData());
    }
}
Categories: Programming Tags: , ,