每次在我的网站上请求页面时,我都会通过以下服务调用记录一些详细信息:
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
对象,而是文件本身。