当我们创建servlet时,为什么类变量(实例和静态变量)不是线程安全的?
为什么方法doPost()
和doGet()
是线程安全的?
我认为每个对servlet容器的新请求都会创建一个新的servlet类实例(扩展HttpServlet
)。每个实例都有自己的类变量存放在内存中,那么我们必须使这些变量线程安全吗?
答案 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