JSP标记类中的synchronized块

时间:2010-05-31 10:31:05

标签: java web-applications file-io jsp-tags concurrentmodification

我试图在过去几天找到以下答案,但无法找到全面的答案

问题陈述

我有一个自定义JSP标记类,它处理Web表单提交,捕获数据并将其写入文件系统中的同一文件。 作为所有Web应用程序,这可以同时触发,我担心多个线程将处理每个提交(我们都知道Servlet是如何工作的。)

CODE

                        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());
                        }

ISSUE: - 一个线程可以打开一个File对象进行写入,同时另一个线程可能会尝试访问并失败并抛出异常 所以我想同步(在对象上)应该解决问题,但是读一些 jsp引擎会有jsp标签对象池的地方,所以我担心 synchronized(this)不会工作,应该更改为 synchronized(this.getClass()) 仅供参考:上面的代码放在JSP自定义标记类中。

编辑:

问题1:应该通过 synchronized(this) synchronized(this.getClass())

问题2:如果在群集环境中部署Web应用程序,将如何处理相同的方案?

3 个答案:

答案 0 :(得分:1)

我会在更精细的级别进行同步,并选择一个与文件创建更紧密相关的对象。

e.g。将上面的内容抽象为一个FileManager类,并让一个单个实例在锁定对象上同步(在FileManager内部保持 - 它可能会自行锁定,也许)。

通过这种方式,您可以更精细地控制同步,并且可以更好地控制要锁定的对象。它们不受servlet / web容器的控制。

答案 1 :(得分:0)

如何将它放在同步方法中,以便您可以高兴地忽略JSP的管理细节?

答案 2 :(得分:0)

我会查看java.util.concurrent包中的内容。

您可以使用cuncurrent队列来推送更新,并在另一端使用在应用程序启动时生成的线程,该线程会对文件系统进行写入。

这将很好地有效地序列化对该文件的访问。