Reading a user credentials from file concurrently I came across the following code snippet:

static private volatile ConfigUserCredentails maintenanceUserCred = null;
static private Object maintenanceUserLock = new Object();

/**
 * This method is slower.  Recommend use the one from cache.  
 *
 * @return The username/password credentials of the maintenance user.
 * @throws IOException
 */
public static ConfigUserCredentails getMaintenanceUserCredentials() throws IOException {
    return readCredentialsFromFile(MAINTENANCE_CREDENTIALS_PROPS, Crypt.getDefaultCrypt());
}

/**
 * 
 * @return The username/password credentials of the maintenance user.
 * @throws IOException
 */
public static ConfigUserCredentails getMaintenanceUserCredentialsFromCache() throws IOException {
    if (maintenanceUserCred != null) {
        return maintenanceUserCred;
    }
    synchronized(maintenanceUserLock) {
        if (maintenanceUserCred == null) {
            maintenanceUserCred = getMaintenanceUserCredentials();
        }
    }
    return maintenanceUserCred;
}


'getMaintenanceUserCredentials()' just reads the user credentials from file and
creates new user object.

My questions are:


What is the purpose of 'volatile'?
Why would one need the 'synchronized' block?


Thanks,
Rafik
When a variable is volatile, then the code that access that variable is forced to read/write the value of variable from/to the memory. Without volatile, the value of variable can be (temporarily) stored to place (like register/cache) where changes are not immediately visible to other threads, or changes by other threads are not immediately visible.
synchronized is used in the code for avoiding concurrent and duplicate initialization of maintenanceUserCred. Without the synchronized block, two or more threads can enter to maintenanceUserCred = getMaintenanceUserCredentials(); line at the same time. The synchronized will pass only one thread at a time to the block, so maintenanceUserCred = getMaintenanceUserCredentials(); will be done only once. 


Both synchronized and volatile will create memory barriers, that ensures that loads and stores are really from/to the main memory (not only local cache of current CPU core). 

For example without volatile and synchronized the generated code could effectively work like the following code:

ConfigUserCredentails tmp = maintenanceUserCred;

if (tmp != null) {
    return tmp;
}
tmp = getMaintenanceUserCredentials();
maintenanceUserCred = tmp;
return tmp;


That will allow several threads to call getMaintenanceUserCredentials() at the same time and threads may obtain different ConfigUserCredentails objects.