java Web应用程序中的线程安全?

时间:2014-07-28 09:00:02

标签: java java-ee thread-safety

当我被问及我的网络应用程序是否是线程安全时,有人意味着什么,考虑到我没有在我的网络应用程序中使用多个线程。

3 个答案:

答案 0 :(得分:6)

在正常的Web应用程序中,Servlet视为Singleton类,这意味着如果您在Servlet中使用非线程安全的实例变量,那么它将为同时提供的多个请求创建一个问题。

  

Java servlet容器/ Web服务器通常是多线程的。这意味着,可以同时执行对同一servlet的多个请求。因此,在实现servlet时需要考虑并发性。

Read more...

enter image description here

  
    

当我被问及我的网络应用程序是否是线程安全的时候,有人意味着什么

  

您必须确保所有Servlet / JSP都是线程安全的。对所有被视为Singleton的服务器端类执行此操作。

  

我的web应用程序中没有使用多个线程。

容器/网络服务器为每个请求启动一个新线程。

答案 1 :(得分:1)

servlet规范要求Web应用程序是线程安全的,因为servlet容器可能(并且通常会)同时处理请求。也就是说,即使你没有启动自己的任何线程,servlet容器也会这样,并且你必须确保你的代码在这种情况下仍然是正确的。

这涉及保护多个线程共享的任何对象(例如HttpSession的内容或任何单例对象)不受并发访问的影响。

答案 2 :(得分:1)

BalusC here给出了类似问题的优秀答案。另请查看Tomasz's answer

通常,实例变量或状态可以跨线程共享(由应用程序或容器创建的线程)。因此,任何暴露其状态以进行修改的类(对象)都可以被认为是不安全的。因此,如果您的服务层调用某些数据访问对象方法并且dao是服务类中的实例变量,那么要问的问题是这个dao或dao本身的状态是否可以被其他客户端更改?

  1. 您可以使对象不可变。您的自定义对象,日期和集合可以是可变的。甚至getter方法可能很危险的一些例子是集合,日期等。使用类似ConcurrentHashMap的东西或返回类似Collections.unmodifiablelist的列表
  2. 另一个例子,你应该写,而不是返回this.someDate public Date getSomeDate() { return new Date(someDate.getTime()); } 这样一些其他线程(可能由容器为另一个用户的另一个请求生成)持有对变量some​​Date的引用将无法搞乱这个线程。

    1. 如果您不能使对象的状态不可变,因为您希望允许其客户端更改其状态,则可以使该对象的所有客户端同意共享该状态。因此,如果一个线程改变了共享对象的状态,而另一个线程可以通过第一个线程更改状态,那么这个monostate对象可以在您的应用程序中使用。
    2. 正如其他答案所提到的,即使您的应用程序没有,容器也会生成线程。我这里主要关注的是答案中没有直接涵盖的主题,以避免重复。希望这会有所帮助。