在过去的几天里,我试图找到以下问题的答案,但找不到全面的答案
问题陈述
我有一个自定义 JSP 标记类,它处理 Web 表单提交、捕获数据并将其写入文件系统中的同一文件。 与所有 Web 应用程序一样,这可以同时触发,我担心多个线程会同时处理每个提交(我们都知道这就是 Servlet 的工作原理。)
代码
synchronized (this){
final String reportFileName = "testReport.csv";
File reportDir = new File( rootCsDirectory, "reports" );
if(!reportDir.isDirectory())reportDir.mkdir();
File reportFile = new File (reportDir, reportFileName);
logReport(reportFile,reportContent.toString());
}
问题: - File 对象可以由一个线程打开进行写入,同时另一个线程可能会尝试访问并失败并引发异常 所以我认为同步(在对象上)应该解决这个问题,但是阅读了一些 jsp 引擎将具有 jsp 标记对象池的内容,所以我担心 synchronized (this) 不起作用,应该更改为 同步(this.getClass()) 仅供引用:上面的代码放置在 JSP 自定义标记类中。
编辑:
问题 1:代码块应该通过 synchronized (this) 同步还是 synchronized (this.getClass())
问题2:如果Web应用部署在集群环境中,同样的场景会如何处理?
最佳答案
我会在更精细的级别上进行同步,并选择与文件创建更紧密相关的对象。
例如将上述内容抽象为一个 FileManager
类,并让该类的单个实例在锁对象上同步(在 FileManager
内部保存 - 它也许可以锁定自身)。
这样您就可以更精细地控制同步,并且可以更好地控制要锁定的对象。它们不受您的 servlet/web 容器控制。
关于java - JSP 标记类中的同步块(synchronized block),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2942909/