Java已在同一个文件上同步,但没有不同



我有一个静态类:

public class FileManager{
....
public static void writeOnFile(String something, String filepath){
File f= new File(filepath);
// Append
PrintWriter writer = new PrintWriter(new FileWriter(f, true));
writer.append(something);
}
...
}

有很多方法,上面的这个就是其中之一。

我想做的是,如果两个调用方对同一个文件进行写入,则应该在互斥的情况下进行写入。但是,当调用方写入不同的文件时,这种情况不会发生(它们不会以互斥方式写入(。

以下版本:

public class FileManager{
....
public synchronized static void writeOnFile(String something, String filepath){
File f= new File(filepath);
// Append
PrintWriter writer = new PrintWriter(new FileWriter(f, true));
writer.append(something);
}
...
}

我不认为这是我想要实现的。在这种情况下,调用方将以互斥方式进行写入,即使它们写入的文件不同。

我想问:这个第二个版本:

public class FileManager{
....
public static void writeOnFile(String something, String filepath){
File f= new File(filepath);
// Append
synchronized(f){
PrintWriter writer = new PrintWriter(new FileWriter(f, true));
writer.append(something);
}
}
...
}

会起作用吗?。如果没有,我是否必须创建一个包含每个文件的文件路径的对象,才能按照我的意愿使用锁?

同步只有在同一个实际对象上完成时才能工作。您的第二个版本将不起作用,因为它会创建一个新对象,从而创建一个新锁。您需要的是一个锁的注册表。一个小例子,使用未同步但ReentrantLock:

private static final Map<String, Lock> LOCKS = new ConcurrentHashMap<>();
...
Lock lock = LOCKS.computeIfAbsent(filepath, p -> new ReentrantLock());
lock.lock();
try {
....
} finally {
lock.unlock();
}

每次使用相同的filepath值调用方法时,ConcurrentHashMapcomputeIfAbsent的组合应产生相同的Lock对象。

另一种选择可能是使用FileLock。它使用本机锁定机制(如果它确实存在的话(,并且基于实际的文件,而不是Java对象。

最新更新