Reputation: 25950
I'm trying to write a piece of code that allows me to install a library (i.e. download an archive from a remote endpoint and uncompress it on disk) once per JVM (may have several JVMs per machine but it's not the point of the question).
I'm aware of the flaws of the DCL technique regarding memory synchronization, but I'm not sure if I should be concerned by this in my case since my state is on disk.
Can you find any race condition in the following snippet? I couldn't find any information about the thread-safety of filesystem operations in the standard library's documentation (well, some methods are explicitly guaranteed to be atomic but nothing is said about the rest of them).
public class LibraryInstaller {
// singleton state
private static AtomicBoolean IS_INSTALLED = new AtomicBoolean();
// this method will be called hundreds of millions of times. I could remove this requirement but it would force me
// to use a dirty hack (the justification for that is out of scope)
public static void ensureInstalled() {
// double-checked locking to allow faster access after the initial installation
if (IS_INSTALLED.get()) return;
synchronized (LibraryInstaller.class) {
if (!IS_INSTALLED.get()) install();
}
}
// takes several minutes
private static void install() {
downloadLibraryAndUncompressOnDisk();
IS_INSTALLED.set(true);
}
}
Upvotes: 2
Views: 83
Reputation: 2305
The problem you could run into is that you could potentially block many threads for several minutes, while one thread is inside install(). Not sure what the consequences of that would be in your application. But apart from that your code should work fine and the state of IS_INSTALLED should be visible to all threads just fine.
You should be even able to use a simple private static volatile boolean IS_INSTALLED
Upvotes: 2