mkdirs() function in multithreaded environment

The File.mkdirs() method is specified to create the directory, and all its parents, if they don't exist. Ergo there's no point in calling exists(). Existence will get checked anyway. Calling exists() is just wasting time. mkdirs() is essentially an atomic operation: there is really no point in trying to out-think it.

Note that a return value of false isn't necessarily a failure. It might just indicate that all the directories in the path already existed.

Basically the premiss of your question is false.


None of the answers seem to address the issue of whether mkdirs() is thread safe, one answer states that mkdirs() is atomic but there might exist cases where this fails. This function essentially deals with the file system so it probably involves a system call to the operating system on the respective host, and determining whether those system calls are actually thread safe could be impossible if you don't already know the target system your application will be used on.

For example, even though mkdirs() checks for existence before creating the folder structure what would happen in the following case,

Thread 1 calls mkdirs(), it inherently checks for the existence of the folder structure and determines it doesn't exist. At that time, Thread 1 gets pre-empted.

Thread 2 calls mkdirs(), it inherently checks for the existence of the folder structure and determines that it doesn't exist and subsequently moves on to create the folder structure.

Thread 1 starts up again and contines to try creating the folder structure with the previous determination that it didn't exist before.

What happens there? I don't know, this sequence of events would be hard to test and especially with the knowledge that the create folder system call varies between operating systems. Your best bet for thread safety and to avoid introducing errors that would be potentially difficult to track and debug would be to implement a degree of mutual exclusion at this critical section in the code.

I guess it would be easy to take a naive approach and declare a single 'global' variable that both threads would have access to, for example a Boolean b and then add the following code around your critical section,

synchronized(b) {
     // Your critical section here
}

This would guarantee that if one thread has locked b it alone will only get to access the critical section while the other one waits, thus making sure that mkdir() won't get called by both threads.

However, if you want to learn more about multi-threading and how to implement mutual exclusion on a lower level, in this case I'd suggest you look at semaphores and how they could be implemented to solve this.