javamultithreadingspringmkdirs

mkdirs() function in multithreaded environment


I am creating tree of files and folder. I am rewriting to multithreading. The only weak point I see is when creating folders. Right now it goes one by one (in depth). Before I write down the file I check if the path exists. If not, I use mkdirs to create all that is missing.

public void checkDir(String relativePath) {
        File file = new File(homePath + relativePath);
        if (!file.exists()) {
            if (file.mkdirs()) {
                log.info("Directory: " + homePath + relativePath + " is created!");
            } else {
                log.error("Failed to create directory: " + homePath + relativePath + " !");
            }
        }
    }

I have a question what happens when I use two threads. One has path A/B/C and the other one A/B/D. Let's say I have only A folder existing but not B. So both of them will check that the path doesn't exist and want to create it. So one of them will probably fail because the other one will be faster. So how can I manage this?

  1. I was thinking about removing the exists condition and leave it fail but there is no AlreadyExists exception I could catch..
  2. Create directory tree first (but I think there will be better way?)
  3. Put directory creation as critical section and make it sequential - not sure how to do this in spring, but anyway hot sure it is neccessary and won't slow down the process too much.

Maybe I am overthinking too much, but theoretically such situation might happen. Currently I use regular Thread, but I want to use spring TaskExecutor for this. It handles critical sections on its own, but this is not shared variable or anything and the path is different so I think it won't recognize it.

Thanks for suggestions.


Solution

  • 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.