【问题标题】:File issues with threading in tomcatTomcat中线程的文件问题
【发布时间】:2013-02-05 13:16:39
【问题描述】:

我有一个 tomcat 服务器,我有一个控制器,它写入一个文件,数据来自请求。所以我怀疑服务器内的多个线程是否可以同时写入同一个文件并导致问题?

我的要求是所有请求都将数据附加到同一个文件中。我没有使用任何线程。

我的代码如下:

File file = new File(fileName); 
try { 
    if(!file.exists()) { 
        file.createNewFile();    
    }
    InputStream inputStream = request.getInputStream();
    FileWriter fileWriter = new FileWriter(fileName,true);
    BufferedWriter bufferWriter = new BufferedWriter(fileWriter);
    bufferWriter.write(IOUtils.toString(inputStream));
    bufferWriter.flush(); 
    bufferWriter.close(); 
}

【问题讨论】:

  • 您是在每次请求时打开文件还是都共享同一个作者?
  • 现在我每次都打开文件。我的代码如下 -File file = new File(fileName);尝试 { if(!file.exists()) { file.createNewFile(); } InputStream inputStream = request.getInputStream(); FileWriter fileWriter = new FileWriter(fileName,true); BufferedWriter bufferWriter = new BufferedWriter(fileWriter); bufferWriter.write(IOUtils.toString(inputStream)); bufferWriter.flush(); bufferWriter.close(); }

标签: java tomcat servlets spring-mvc


【解决方案1】:

此类问题有标准解决方案。

您必须创建singleton 类,它将在所有线程之间共享。

这个singleton 将包含一些BlockingQueue(例如LinkedBlockingQueue),所有线程都会将它们的消息放入单个文件中写入。

这个singleton本身也将是Thread,在它的run()方法中,它会不断地take来自queue的值并将其写入所需的文件中。

【讨论】:

  • 最好在ServletContext 中存储对象的实例(应该写入文件)而不是创建单例。当您需要一个对象可供所有其他组件访问时,这是在 Java Web 应用程序中采用的方法。
【解决方案2】:

我的要求是所有请求都将数据附加到同一个文件中

最好使用过滤器 (javax.servlet.Filter) 为每个请求执行一项任务(例如记录日志或在您的情况下将文本附加到文件)。您不必手动创建单例,您可以在需要或不需要其功能时打开或关闭过滤器。

但是,您仍然需要同步对文件的并发访问。正如 Andremoniy 指出的那样,您可以使用自己的线程来执行此操作,这样您的过滤器就不会阻塞请求/响应。

编辑

关于用于写入文件的共享对象的一件事:最好将这个对象的一个​​实例存储在javax.servlet.ServletContext 中,而不是创建一个单例对象。如果您需要使用 servlet 让 Java Web 应用程序中的所有其他组件都可以访问一个对象,这是标准方法。

【讨论】:

  • 那么tomcat服务器不会负责同步线程吗?
  • @user1643001 当然不是。它竭尽全力确保它们都可以同时运行。否则它不会很好用,你也不会使用它。
  • 我们可以使用同步块吗?
  • @user1643001 是的,你可以。基本上,你可以使用你在 Java 中知道的任何同步方法。
猜你喜欢
  • 2011-02-20
  • 2013-02-15
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 2015-08-30
相关资源
最近更新 更多