gpt4 book ai didi

java - javax.servlet.Servlet#getServletConfig() 的线程安全

转载 作者:行者123 更新时间:2023-11-28 22:26:55 25 4
gpt4 key购买 nike

我想知道为什么要调用 javax.servlet.Servlet#getServletConfig()是线程安全的:如果你检查实现 javax.servlet.GenericServlet从 servlet API 3.0.1 开始,您会看到以下内容:

package javax.servlet;

// lines omitted

public abstract class GenericServlet
implements Servlet, ServletConfig, java.io.Serializable
{
// lines omitted

private transient ServletConfig config;

// lines omitted

public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}

// lines omitted

public ServletConfig getServletConfig() {
return config;
}
// lines omitted
}

字段config写在init(ServletConfig)没有任何同步、锁定或 config不稳定,而getServletConfig()可以随时从 servlet 容器的任何后续工作线程调用。我快速查看了 Tomcat/Catalina 代码库,但是我没有看到 servlet 容器执行任何魔法的迹象,这将保证对字段 config 的线程安全访问。通过getServletConfig()来自例如javax.servlet.GenericServlet#service(ServletRequest, ServletResponse)以及 javax.servlet.http.HttpServlet 中的相应方法.

我是不是漏掉了什么?如果使用线程 A 将保证什么 init(ServletConfig)然后线程 B 调用 getServletConfig()将看到字段的正确状态 config (Java “发生在”),而不是例如null

最佳答案

ServletConfig 是一个单例对象(由容器管理),您仅使用它来检索 init-parameters 或获取 servletcontext 或在 servlet init 阶段设置的 servletname。您不能向 ServletConfig 对象写入任何内容,而是由容器单独管理该对象,因此它是线程安全的。

字段配置是在 init(ServletConfig) 中编写的,没有任何同步、锁定或配置是易变的,而 getServletConfig() 可以随时从 servlet 容器的任何后续工作线程调用?

GenericServlet 是一个抽象类,容器不会为其创建任何对象,而是容器为自定义 HttpServlet 创建一个对象(默认情况下只有一个实例)您编写/提供的类,用于初始化 ServletConfig 对象。

问题是关于 getServletConfig() 而不是 ServletConfig 的线程安全?

一旦容器在 servlet 生命周期的 init 阶段创建了 ServletConfig 对象,它就永远不会被更改。因此,getServletConfig() 是线程安全的(即,有多少线程读取 ServletConfig 对象并不重要,只要不允许任何线程向其写入任何内容即可) .

UPDATED QUESTION:

What will guarantee that if Thread A is used to init(ServletConfig) then Thread B calling getServletConfig() will see the correct state of the field config (Java "happens-before"), and not e.g. null?

servlet 容器在实例化 servlet 后恰好调用一次 init 方法。 在 servlet 可以接收任何请求之前,init 方法必须成功完成。如果 init 方法抛出 ServletException 或未在 Web 服务器定义的时间段内返回,则 servlet 容器无法将 servlet 投入服务。你可以看看here

用户请求线程的创建仅在 init() 方法成功完成之后发生。因此,不需要数据 (servletconfig) 之间的同步用户请求线程,因为 servletconfig 对象甚至在用户请求线程创建之前就已经可用

关于java - javax.servlet.Servlet#getServletConfig() 的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40485403/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com