为啥我的 servlet 不根据请求创建新线程? [关闭]

Posted

技术标签:

【中文标题】为啥我的 servlet 不根据请求创建新线程? [关闭]【英文标题】:Why my servlet do not creates a new thread on a request? [closed]为什么我的 servlet 不根据请求创建新线程? [关闭] 【发布时间】:2015-09-30 17:54:04 【问题描述】:

我的结构如下:

然后我多次请求main.java,声明一个变量并在每次调用时递增它,这反映了旧值。我是否遵循正确的方法?为什么不是每次都创建一个新线程?

【问题讨论】:

对您发出的每个请求都有一个新请求,尽管请求之间共享一个 SINGLE servlet 实例。要增加一个变量,您必须在请求范围之外声明它。 (即在 Servlet init() 方法中)然后在每次调用 servlet 时递增它。 @Down-voter 请随时添加评论和您的意见。如果您需要一些代码或更多规范,请发表评论。 @GilesThompson 每次请求都会创建新线程吗?正如您所说的资源,那么它可能会冲突或造成 A、B、C Java 文件的资源不一致? 取决于您的 servlet 实现。通常,tomcat 将利用线程池并分配一个新线程来服务您发出的每个请求。然而,所有线程将“看到”同一个 servlet 实例,但会使用自己的数据调用 servlet get 方法,因为每个线程都有自己的堆栈。因此,要使变量对所有线程可见,您必须在方法范围之外声明它,就像我在回答中所做的那样;然后每个线程将能够更新该变量。此外,您可能希望同步对变量的访问以防止损坏。 您可以添加代码以便更好地解释 【参考方案1】:

在 get/post 方法范围之外声明变量,然后您将能够在每次调用 servlet 时递增它。见下文:

private int counter;

private Object lock;

public void init() throws ServletException
  //init lock
  lock = new Object();
  // create variable 
  counter = 0;



public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  //increment your counter here
  synchronized(lock)
  counter++;
  
  response.setContentType("text/html");

  // here you can actually return the counter to the browser.
  PrintWriter out = response.getWriter();
  out.println("<h1>" + counter + "</h1>"); 

【讨论】:

counter 变量不能是synchronized 你说的很对,我已经更新了我的答案以反映这一点;而是在初始化时创建一个锁,然后用于同步对共享计数器变量的访问。 我明白,但是这些变量实际上是如何为各种请求设计的?一般的实现是否包括/有同步块?他们没有自己变量的副本? 而恰恰相反,我不想共享变量。我以为每个请求都带有自己的变量。那它们怎么会相互影响? 适用于标准 java 类的相同变量范围访问规则也适用于 Servlet; Servlet 只是由 Tomcat 等 servlet 容器执行的类。因此,在方法范围内创建的变量(例如,请求 get/post 方法)是线程私有的——每个线程都有自己的该变量的线程本地副本。相反,实例变量(如我的示例中的计数器)在线程之间共享,因此我的示例从同步块中访问计数器变量的原因。

以上是关于为啥我的 servlet 不根据请求创建新线程? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Servlet第二篇Servlet实现线程安全及其他细节补充

servlet3.0 新特性——异步处理

java servlet

为啥我的工作线程没有使用 python 多线程产生

为啥我的工作线程没有使用 python 多线程产生

为啥不创建单独的线程?