The following method does not access any shared variable. It is still not thread safe. I am either testing wrong or I am missing something. Please explain.
Method:
public static boolean acquireFolderLock(File directoryPath) {
final String LOCK_FILE_NAME = ".lock";
boolean isLocked = false;
if(directoryPath != null && directoryPath.isDirectory()) {
File lockFile = new File(new StringBuilder(directoryPath.getAbsolutePath()).append(File.separatorChar).append(LOCK_FILE_NAME).toString());
if(lockFile.exists()) {
isLocked = false;
} else {
try {
lockFile.createNewFile();
isLocked = true;
} catch(IOException ioex) {
isLocked = false;
}
}
}
return isLocked;
}
Thread class for Testing
class AThread extends Thread {
String name;
public AThread(String name) {
this.name = name;
}
@Override
public void run() {
File f = new File("C:\\TEMP\\DIRECTORY");
System.out.println(name + ": " + Util.acquireFolderLock(f));
}
}
And the main method which starts the threads
public static void main(String[] args) throws Exception {
for(int i = 1; i <= 100; i++) {
(new AThread("Thread-->" + i)).start();
}
}
The method checks whether a file exists and later, it creates it. That means one thread could have done the statement
if (lockFile.exists())(outcome:false) when another thread is doinglockFile.createNewFile();(and thus, it creates the lock file).The first thread is now continuing based on incorrect information: it thinks the file does not exist but it has been created already by another thread.
Thread safety is not just about shared variables, it’s about shared resources (be it variables, databases, filesystems, network connections, etc).