Sam
Sam

Reputation: 2065

Thread safety when file renaming

I am having some concerns regarding the following code.

public class Task implements Runnable {

String filePath = "C:\\Backup\\test.xml";

@Override
public void run() {

    File file = new File(filePath);

    try {

        System.out.println(Thread.currentThread() + " Renaming " + FileUtil.changeFileExtention(file));
        Thread.sleep(20000);
        System.out.println(Thread.currentThread() + " Renaming Back " + FileUtil.changeFileExtention(file));

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

here is the `FileUtil' is a class.

public class FileUtil {

public static File changeFileExtention(File file) throws Exception {

    File newFile = null;

    int extIndex = file.getName().lastIndexOf(".");

    String ext = getExtentionFromFile(file);

    System.out.println("File Extention is [" + ext + "] for file [" + file.getName() + "].");

    if (ext.equalsIgnoreCase(".xml")) {

        newFile = buildChangedFile(file, extIndex, ".txt");

    } else if (ext.equalsIgnoreCase(".proc")) {

        newFile = buildChangedFile(file, extIndex, ".xml");
    }

    file.renameTo(newFile);

    return newFile;

}

public static String getExtentionFromFile(File file) throws Exception {

    String fileName = file.getName();

    int extIndex = fileName.lastIndexOf(".");

    if (extIndex != -1) {

        return fileName.substring(extIndex);

    } else {

        String msg = "File extention not found for file [" + fileName + "]";
        System.out.println(msg);
        throw new Exception(msg);
    }
}

private static File buildChangedFile(File file, int extIndex, String targetExtention) throws Exception {

    String fileName = file.getName();

    File renamedFile = null;

    if (file.exists()) {

        String newFileName = fileName.substring(0, extIndex) + targetExtention;

        System.out.println("New File name -" + newFileName);

        String fullPathWithName = file.getParent() + "/" + newFileName;

        renamedFile = new File(fullPathWithName);

    } else {

        String msg = "File not exisit in location [" + file.getAbsolutePath() + "]";
        System.out.println(msg);
        throw new Exception(msg);
    }

    return renamedFile;
}

}

here is my test class -

public class Test {


public static void main(String[] args) {

    Thread thread1 = new Thread(new Task());
    Thread thread2 = new Thread(new Task());
    Thread thread3 = new Thread(new Task());

    thread1.start();
    thread2.start();
    thread3.start();
}

}

what i need is if one thread took the file other threads need to ignore that file. am not much clear about the thread process here and have some confusion.

  1. do i need to make the renaming process in synchronize block ?
  2. is my FileUtil methods are thread safe?
  3. since Task class create a new instance for every thread, every thread should have its own file object. since objects are created in the heap in this case would it be shared ? or will one thread have its own object stack in the heap?
  4. what will happen if two threads try to rename the file in the same time? (should i need to make my util methods synchronize ?)

highly Appreciate your help to clear my confusion. Thank you all in advance.

Upvotes: 0

Views: 1702

Answers (1)

Erdinç Taşkın
Erdinç Taşkın

Reputation: 1578

Obviously if you have one file to change name there is no need to multiple threads. Otherwise , this is look likes typical consumer-producer problem. As an alternative sol'n you can use blockingQueue structure to use thread safety. One (or more) thread add to file names to queue and all consumer threads take a filename to change its name.

You can check LinkedBlockingQueue

Upvotes: 1

Related Questions