Singleton with a volatile and synchronized instance I created a singleton to have a unique instance of ExecutorService in my application.

I whould like to know which is the better of the two classes below. 

First one : 

public class ExecutorServiceSingleton {
    private static final Logger LOG = LoggerFactory.getLogger(ExecutorServiceSingleton.class);
    private ScheduledExecutorService scheduledExecutorService;

    private static ExecutorServiceSingleton instance;

    private ExecutorServiceSingleton() {
        scheduledExecutorService = Executors.newScheduledThreadPool(1);
    }

    /**
     * Method to run the task
     */
    public void runTask(Runnable task) {
        scheduledExecutorService.submit(task);
    }

    /**
     * Get the instance : If the instance is null, then we return a new one. If the instance is diff than null, then, we use the instance value and we return it.
     *
     * @return the instance
     */
    public static ExecutorServiceSingleton getInstance() {
        if (instance == null) {
            instance = new ExecutorServiceSingleton();
        }
        LOG.info("Instance: " + instance);
        return instance;
    }
}


Second one : 

public class ExecutorServiceSingleton {
    private static final Logger LOG = LoggerFactory.getLogger(ExecutorServiceSingleton.class);
    private ScheduledExecutorService scheduledExecutorService;

    private volatile static ExecutorServiceSingleton instance;

    private ExecutorServiceSingleton() {
        scheduledExecutorService = Executors.newScheduledThreadPool(1);
    }

    /**
     * Method to run the task
     */
    public void runTask(Runnable task) {
        scheduledExecutorService.submit(task);
    }

    /**
     * Get the instance : If the instance is null, then we return a new one. If the instance is diff than null, then, we use the instance value and we return it.
     *
     * @return the instance
     */
    public static ExecutorServiceSingleton getInstance() {
        if (instance == null) {
            synchronized (ExecutorServiceSingleton.class) {
                if (instance == null) {
                    instance = new ExecutorServiceSingleton();
                }
            }
        }
        LOG.info("Instance: " + instance);
        return instance;
    }
}
The memory model of the jvm doesn't allow double checked locking like that to work like you think it does. The jvm is allowed to assign the object before running the constructor.



In java class loading is already lazy and perfectly thread safe. So the naive 

private static final ExecutorServiceSingleton instance = new ExecutorServiceSingleton();


is fine for most purposes.

If you really want the lazy ness to go further then something like: 

private static class Nested{
    private static final ExecutorServiceSingleton instance = new ExecutorServiceSingleton();
}

public static ExecutorServiceSingleton getInstance() {

    return Nested.instance;
}


will do what you need.