Mkdirs () function in multi-threaded environment

I create a tree of files and folders. I am rewriting multithreading. The only weak point that I see is the creation of folders. Now he goes one after another (in depth). Before writing a file, I check if the path exists. If not, I use mkdirs to create everything 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 + " !");
            }
        }
    }

My question is what happens when I use two threads. One has an A / B / C path, and the other A / B / D. Say I have only folder A, but not B. Thus, both of them will check that the path does not exist and needs to be created. Therefore, one of them is likely to fail, because the other will be faster. So how can I do this?

  • I thought about deleting the existing condition and left it unsuccessful, but there is no AlreadyExists exception that I could catch.
  • ( , ?)
  • - , spring, , .

, , . Thread, spring TaskExecutor. , - , , , .

.

+6
3

File.mkdirs() , . Ergo exists(). . exists() - . mkdirs() - , , : .

, false . , .

.

+7

, , mkdirs() , , mkdirs() , , . , , , , , , , , , , .

, mkdirs() , ,

Thread 1 mkdirs(), , . Thread 1 .

Thread 2 mkdirs(), , , .

1 , , .

? , , , create folder . , , .

, "" , , b, ,

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

, b, , , , mkdir() .

, , , .

+5

EJP, false , , . , , :

public final class DirectoryHelper {
   private DirectoryHelper(){}

   public static boolean createDirectories(File path) {
      if (path.mkdirs()) return true; //definitely has new dir
      // if false, just look afterwards for the existence of the directory
      // also opportunity to throw own exceptions if you prefer
      return path.exists() && path.isDirectory();
   }
}

I wrote a new method here that returns false only if the directory does not exist. I don’t care that this is already done or already exists. Due to the new order, I don't need a block synchronized.

Then your code looks like this:

public void checkDir(String relativePath) {
    File file = new File(new File(homePath), relativePath);
    if (!file.exists()) { // just to prevent logging of existing dirs
        if (DirectoryHelper.createDirectories(file)) {
            log.info("Directory: " + file + " is created!");
        } else {
            log.error("Failed to create directory: " + file + " !");
        }
    }
};
+1
source

All Articles