线程安全的servlet

时间:2012-01-14 09:29:07

标签: java multithreading servlets

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

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

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

2 个答案:

答案 0 :(得分:9)

servlet仅在加载时实例化一次:然后,当客户提出请求时,它就是线程化的。

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

由于doGet和doPost依赖于请求,因此它是线程安全的:如果您打算在doGet和doPost中执行原子操作,则应考虑创建同步方法/块。

答案 1 :(得分:1)

  

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

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

  

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

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

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

  

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

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

您可以在这篇文章中找到好消息:

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