如何在Java中安全地操作文件线程



每次在我的网站上请求页面时,我都会通过以下服务调用记录一些详细信息:

logService.logPageRequest(session, request, contentId);

此服务调用使用静态FileUtils(我自己的)方法对文件进行实际更新。

public static void appendToTextFile(String string, String fileRootDirectory, String subdirectory, String filename, boolean startOnNewLine) throws Exception {
// code irrelevant to the question removed
String filePath=fileDirectory+"/"+filename;
File file=new File(filePath);
if(file.exists()) {
FileWriter out = new FileWriter(filePath, true);
if(startOnNewLine) {
out.write("rn");
}
out.write(string);
out.close();
} else {
FileWriter out = new FileWriter(filePath);
out.write(string);
out.close();
}

每隔一段时间(比如说每15分钟安排一次),我就会执行另一项服务,重命名这个文件并开始处理它

我想了解如何确保两个并发写入都是安全的,并且在写入过程中不会执行重命名。我想答案将是某种形式的同步。

这两个服务需要共享一个同步对象:它可以是任何东西(甚至是new byte[1]),但它必须是传递到您的"服务"中的同一个实例。只要有关键部分,这意味着代码的一部分想要在共享资源上操作,就需要将其封装在中

synchronized(theInstanceOfSynchronizationObject) {
// ... your code for critical section
}

好的锁定规则是确定地知道你锁定了什么,什么是共享资源。为了"解决"问题,随机添加同步块会杀死你(并导致死锁)。在您的特定示例中,很可能是file上的操作:只是操作,而不是文件名字符串上的操作,也不是File的实例化:您可以让许多File对象指向磁盘上的同一文件并且这不是关键操作,只要它还没有接触到磁盘即可。所以我会说

File file=new File(filePath);
synchronized(theInstanceOfSynchronizationObject) {
if(file.exists()) {
} else {
}
}

同样,保护其他服务中的File操作。请记住,您保护的不是File对象,而是文件本身。

最新更新