【问题标题】:Thread-safe servlets线程安全的 servlet
【发布时间】:2012-02-10 06:59:20
【问题描述】:

当我们创建 servlet 时,为什么类变量(实例和静态变量)不是线程安全的?

为什么doPost()doGet() 方法是线程安全的?

我认为对 servlet 容器的每个新请求都会创建 servlet 类的新实例(扩展 HttpServlet)。这每个实例都有自己的类变量,这些变量托管在内存中,那么为什么我们必须使这些变量线程安全?

【问题讨论】:

  • 通常容器不会为每个请求创建一个新的servlet实例。
  • 你需要知道类变量和局部变量在jvm中的位置。这些变量的作用域是什么。

标签: java multithreading servlets


【解决方案1】:

servlet 仅实例化一次:在加载时。然后当客户端发出请求时,它就会被线程化。

这解释了为什么必须将监视器放在必要的地方等。

由于doGet和doPost依赖于一个请求,它是线程安全的:如果你打算在doGet和doPost中做原子操作,你应该考虑创建同步方法/块。

【讨论】:

  • 谢谢。即,如果我的类没有线程安全的类变量,我应该在同步块中的 doGet(doPost) 方法中使用这个变量,或者我应该将使用这个变量的代码转移到同步方法中并在 doGet(doPost) 中使用这个方法?
  • 如果我必须这样做,我将使用一个同步方法。
【解决方案2】:

当我们创建 servlet 时,为什么类变量(实例和静态变量)不是线程安全的?

Servlets 通常在多线程服务器上运行。因此 servlet 必须处理并发请求,并且应该小心同步对共享资源的访问。共享资源包括内存中的数据(例如实例或类变量)和外部对象(例如文件、数据库连接和网络连接)。由于多个线程可能会改变共享数据的状态,因此共享数据不是线程安全的。

为什么 doPost() 和 doGet() 方法是线程安全的?

如果您在这些方法中使用局部变量,

doPost()doGet() 是线程安全的。如果您在这些方法中改变共享变量(实例或静态变量)的状态,doPost()doGet() 不是线程安全的.

每个实例都有自己的类变量,这些变量托管在内存中,那么为什么我们必须使这些变量线程安全?

一个 Servlet 存在一个实例。像doGet()doPost() 这样的请求在同一个实例上创建多个线程。只要您在这些方法中使用局部变量,代码就是线程安全的。

你可以在这篇文章中找到很好的信息:

How do servlets work? Instantiation, sessions, shared variables and multithreading

【讨论】:

    猜你喜欢
    • 2016-08-24
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    相关资源
    最近更新 更多