根据我的知识和研究,Java中的synchronized
关键字允许同步方法或代码块语句来处理多线程访问。如果我想在多线程环境中锁定文件以进行写入,我必须应该使用Java NIO package中的类来获得最佳结果。昨天,我提出了一个关于为文件I / O操作处理共享servlet的问题,并且BalusC注释很好地帮助解决了这个问题,但是this answer中的代码让我很困惑。我不是要求社区“烧掉那个帖子”或“让他们贬低他”(注意:我没有投票或任何事情,我没有反对的答案),如果代码片段可以,我要求解释被认为是一种好习惯
private static File theFile = new File("theonetoopen.txt");
private void someImportantIOMethod(Object stuff){
/*
This is the line that confuses me. You can use any object as a lock, but
is good to use a File object for this purpose?
*/
synchronized(theFile) {
//Your file output writing code here.
}
}
答案 0 :(得分:4)
问题不在于锁定File对象 - 你可以锁定任何对象,这在某种程度上并不重要。
让我印象深刻的是你使用的是非最终监视器,所以如果你的代码的另一部分重新分配了文件:theFile = new File();
,那么下一个出现的线程会锁定另一个对象并且你没有保证您的代码不再由2个线程同时执行。
如果theFile
是最终的,代码就可以了,虽然最好使用私有监视器,只是为了确保没有其他代码将其用于其他锁定目的。
答案 1 :(得分:2)
如果您只需要在单个应用程序中锁定文件,那么就可以了(假设添加了final
)。
请注意,如果使用不同的类加载器多次加载类,则该解决方案将不起作用。例如,如果您在同一Web服务器中部署了两次Web应用程序,则该应用程序的每个实例都将拥有自己的锁定对象。
正如您所提到的,如果您希望锁定功能强大并且文件也从其他程序锁定,则应使用FileLock(请参阅文档,在某些系统上,不保证所有程序都必须遵守锁)。
答案 2 :(得分:1)
如果你看到:final Object lock = new Object()
你会问吗?
正如@assylias所指出的那样,问题是这里的锁不是final
答案 3 :(得分:1)
Java中的每个对象都可以充当同步锁。它们被称为内在锁。一次只有一个线程可以执行由给定锁保护的代码块。
更多相关内容:http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
对整个方法使用synchronized关键字可能会对您的应用程序产生性能影响。这就是为什么你有时可以使用synchronized块。
您应该记住,锁定引用无法更改。最好的解决方案是使用final关键字。