【问题标题】:Synchronize file object同步文件对象
【发布时间】:2012-08-15 19:49:33
【问题描述】:

据我所知和研究,Java 中的 synchronized 关键字可以同步方法或代码块语句以处理多线程访问。如果我想在多线程环境中锁定文件以用于写入目的,我必须应该使用Java NIO package 中的类以获得最佳结果。昨天,我想出了一个关于处理文件 I/O 操作的共享 servlet 的问题,BalusC cmets 很好地帮助解决了这个问题,但是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.
    }
}

【问题讨论】:

  • +1 因为现在你已经超过 4000 了。
  • @Hassan 无论是谁,无论声誉如何,在您觉得问题/答案有帮助之前不要这样做。
  • @Nandkumar 我确实喜欢这个问题,我只是觉得它很有趣。
  • @LuiggiMendoza:您在链接到Don't use static objects in a Java Web Application... 的 OP 中的评论是什么意思。我不确定你的意思
  • @user384706 Java Web 应用程序中的静态对象可能会导致内存泄漏,因为它们是在您每次部署应用程序时创建的(加载类的位置),但在您取消部署应用程序时它们不会被释放,静态对象保留在 JVM 中,直到您停止它,这意味着关闭 Web 应用程序服务器(Tomcat、JBoss 或您使用的任何东西)。

标签: java synchronized


【解决方案1】:

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

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

如果theFile 是最终的,那么代码就可以了,尽管最好使用私有监视器,以确保没有其他代码将它用于其他锁定目的。

【讨论】:

  • 是的,我很确定在这种情况下,锁是一个文件并不重要(除了你们提到的缺少的final)。如果有的话,它会混淆代码,因为它暗示 JRE 领域和文件系统领域之间存在某种联系,而(可能)不存在。
  • 是的,final 关键字会有所作为,如How Synchronization works in Java? 中所述。让我感到困惑的是使用 File 对象锁定代码块,确实我对文件上的 Java 锁和 OS 锁感到困惑,但我想这些锁是非常不同的。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-11
        • 2011-08-14
        • 2011-04-05
        • 2018-03-30
        • 1970-01-01
        • 1970-01-01
        • 2015-12-24
        • 2011-12-12
        相关资源
        最近更新 更多