【问题标题】:Why do variables not retain their values in Servlets in spite of being shared during multithreading [duplicate]尽管在多线程期间共享变量,为什么变量不保留它们在 Servlet 中的值[重复]
【发布时间】:2016-06-28 15:31:17
【问题描述】:

我有一个简单的 JSP 页面,它的表单采用参数 val 的值

<form action="test">
Insert Value<input type="text" name="val"/>
<input type="submit"/>
</form>


接下来我有一个 servlet test.java,它接受 val 并打印它。 servlet doGet 方法如下所示-

        String val=request.getParameter("val");
        response.setContentType("text/html");
        PrintWriter p=response.getWriter();
        p.println("Value of parameter is "+val);


现在,我读到在初始化过程中只创建了一个 servlet 实例,即只创建了一个 servlet 对象,并且使用多线程处理多个请求。

现在,由于只创建了一个 servlet 实例,因此必须只创建一个变量 val 的实例,它一次只能保存一个值,那么为什么在多个请求期间每个用户都可以访问自己的 @ 值987654329@ ?
val 的值不应该在多个请求之间共享并反映其相应请求的变化吗?
请帮助。谢谢。

【问题讨论】:

  • 我可以看到您将 val 元素的值存储在变量中,如下行 String a=request.getParameter("val");最后,您正在打印 val 属性本身: p.println("Value of parameter is "+val);你能分享一下你在哪里分配这个变量吗?
  • 你的意思是 a 在你的第二个 sn-p 中被称为 val 吗?你知道局部变量是什么以及它们与每个线程的堆栈有什么关系吗?
  • @AmanChhabra 抱歉,这是我的错误。我现在已经更正了代码。
  • @SotiriosDelimanolis 是的。我知道局部变量是什么,但不知道它们与每个线程的堆栈的关系。请解释一下。

标签: java multithreading jsp servlets


【解决方案1】:

除了只有一个 servlet 实例之外,每个 HTTP 请求都在一个线程中执行,因此 doGet 的每次执行都有自己的调用堆栈。以下命令在该堆栈上创建一个局部变量:

String a=request.getParameter("val");

所以,每个线程都有一个调用栈,所以每个线程都有自己的这个变量的版本。

【讨论】:

  • 好的。如果我在函数外部(即类内部)定义一个变量怎么办。该变量是否仍会共享?
  • @Brut3 Forc3 很明显,因为它是一个单例。
  • @J.Mengelle 那么每个线程都会获得该类变量的自己的副本吗?尽管它不是本地的!。
  • 每个 theads 将引用相同的 servlet 实例。所以如果有一个类属性,其作用域是实例,就会被并发操作。没有“副本”。
【解决方案2】:

我不确定你的代码:val 没有定义? 你在哪里运行这些代码行?

假设 val 是:

String val=request.getParameter("val");

你的方法是这样的:

public void doStuff(HttpRequest request){
   ...
}

每个调用都有一个唯一的请求作为参数,因此有一个唯一的“val”参数。

【讨论】:

  • 对不起,我的错。我现在已经更正了代码。
【解决方案3】:

现在您已经更正了代码。对于每个请求,您都在更新 val 属性的值,该值将由最新请求更新:

String val = request.getParameter("val");

因此,如果您想保留该值,请确保您增加 将此变量的范围归类,使其volatile,然后在分配时验证它是否具有任何现有值。

【讨论】:

  • 对不起,但不是我想问的。我的意思是问,因为只有一个 servlet 实例,因此只有一个 val 变量实例,所以不同用户如何根据他们的请求访问 val 。基本上,尽管只有一个实例,但 val 如何存储不同的值。
  • val 不会有单个实例,因为它的范围在函数内。因此,每当调用该函数时,都会创建一个新的 val 属性实例。
  • 另外,如果您将 val 的范围扩大到类,即使这样,对于不同的请求,它也可以具有不同的值,因为您正在更新 val 的值。因此,如果您在类而不是函数中定义 val,然后在分配值时检查它是否具有任何现有值,它将对所有请求具有相同的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多