同步一段代码

时间:2015-12-17 09:07:12

标签: java multithreading file

我有一段java代码,如果不存在则在文件系统中创建一个目录。 这个应用程序是多线程的(运行2个线程),所以有时会发生检查if(!dir.exists())为两个线程返回true,然后在内部代码中我调用dir.mkdirs()一个返回true创建目录而另一个返回false,让我告诉你代码:

public void makePath(){
        File path = new File(Main.getPath());
            synchronized (this) {
                if (!path.exists()) {//return true on both treads
                    if (path.mkdirs()) {//return true only on one thread
                        logger.warn("Path was not existing, just created one");
                    } else {//returns false only on one thread
                        logger.warn("Problems while creating pth");
                    }
                }
            }
    }

我的初始版本没有同步块,我认为这可以解决问题,但事实并非如此。 当我使用单个线程运行时,一切都很顺利,只有一个线程,!path.exists()只返回true一次。

3 个答案:

答案 0 :(得分:3)

这是因为你在内部类中进行同步。

synchronized (this) 

它不能是this,它可能是此方法的一些其他对象,就像它可以是一个字段

您可以像这样更改代码:

synchronized (Foo.class) 

答案 1 :(得分:2)

如果在this上同步(任何类的当前实例定义方法),那么这不会阻止另一个实例同时运行同一个块,因为它将自行同步。您需要同步同一个对象。

E.g。

private static Object syncKey = new Object();
public void makePath() {
    synchronized (syncKey) {
        ...
    }
}

答案 2 :(得分:0)

我已修复它委派函数来创建文件或检查它们是否存在于Util。然后,可调用实例调用此方法,而不是单独创建文件

    /**
 * Create a directory and its sub directories in a synchronized way
 * 
 * @param file
 * @return
 */
public static synchronized boolean createDirsIfNecessary(String path) {
    File file = new File(path);
    if (!file.exists()) {
        file.mkdirs();
        return true;
    }
    return false;
}