8

据我所知和研究,synchronizedJava 中的关键字可以同步方法或代码块语句来处理多线程访问。如果我想在多线程环境中锁定文件以用于写入目的,我必须使用Java NIO 包中的类以获得最佳结果。昨天,我提出了一个关于处理文件 I/O 操作的共享 servlet 的问题,BalusC 的注释对解决方案很有帮助,但是这个答案中的代码让我感到困惑。我不是在要求社区“烧掉那个帖子”或“让我们对他投反对票”(注意:我没有投反对票或其他任何事情,我没有反对答案),我要求解释代码片段是否可以被认为是一种好的做法

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.
    }
}
4

4 回答 4

4

问题不在于锁定 File 对象-您可以锁定任何对象,这并不重要(在某种程度上)。

令我印象深刻的是您使用的是非最终监视器,因此如果您的代码的另一部分重新分配 theFile: theFile = new File();,则出现的下一个线程将使用不同的对象锁定,并且您无法保证您的代码不会不再由 2 个线程同时执行。

已经theFile完成了,代码就可以了,尽管最好使用私有监视器,只是为了确保没有另一段代码将它用于其他锁定目的。

于 2012-08-15T19:55:43.110 回答
2

如果您只需要在单个应用程序中锁定文件,则可以(假设final已添加)。

请注意,如果您使用不同的类加载器多次加载该类,则该解决方案将不起作用。例如,如果您有一个 Web 应用程序在同一个 Web 服务器中部署了两次,则该应用程序的每个实例都将拥有自己的锁定对象。

正如您所提到的,如果您希望锁定功能强大并且文件也从其他程序锁定,您应该使用FileLock(请参阅文档,在某些系统上,不能保证所有程序都必须遵守锁定)。

于 2012-08-15T20:21:56.863 回答
1

你看到了吗:final Object lock = new Object()你会问吗?
正如@assylias 指出的问题是锁不在final这里

于 2012-08-15T19:57:10.163 回答
1

Java 中的每个对象都可以充当同步锁。它们被称为内在锁。一次只有一个线程可以执行由给定锁保护的代码块。

更多信息:http: //docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

对整个方法使用 synchronized 关键字可能会对您的应用程序产生性能影响。这就是你有时可以使用同步块的原因。

您应该记住不能更改锁定引用。最好的解决方案是使用 final 关键字。

于 2012-08-15T20:07:56.403 回答