1

在过去的几天里,我试图找到以下问题的答案,但找不到全面的答案

问题陈述

我有一个自定义 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());
                        }

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

编辑:

问题1:代码块应该通过synchronized(this)还是synchronized( this.getClass ())来同步

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

4

3 回答 3

1

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

例如,将上述内容抽象为一个FileManager类,并让该类的单个实例在锁定对象上同步(在内部保存FileManager-它可能会锁定自身)。

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

于 2010-05-31T10:33:44.140 回答
1

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

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

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

于 2010-05-31T10:37:55.443 回答
0

将它放在同步方法中怎么样,这样您就可以愉快地忽略 JSP 如何管理的细节?

于 2010-05-31T10:37:23.647 回答