Why do variables not retain their values in Servlets in spite of being shared during multithreading
我有一个简单的JSP页面,它有一个取参数val值的表单。
1 2 3 4
| <form action="test">
Insert Value<input type="text" name="val"/>
<input type="submit"/>
</form> |
接下来我有一个servlet test.java,它接受val并打印它。servlets doGet方法如下-
1 2 3 4
| String val =request. getParameter("val");
response. setContentType("text/html");
PrintWriter p =response. getWriter();
p. println("Value of parameter is"+val ); |
现在,我已经了解到在初始化过程中,只创建了一个servlet实例,即只创建了servlet的一个对象,并且使用多个线程处理多个请求。现在,由于只创建了一个servlet实例,因此一次只能创建一个可保存一个值的变量val实例,那么为什么在多个请求期间,每个用户都可以访问自己的val值?EDOCX1[0]的值是否应该在多个请求之间共享,并反映其在相应请求中的变化?请帮忙。谢谢。
- 我可以看到您正在按照下面的行字符串a=request.getparameter("val")将val元素的值存储在一个变量中,最后您正在打印val属性本身:p.println("value of parameter is"+val);您能分享一下您在哪里准确地分配这个变量吗?
- 在第二个代码片段中,您是指a被称为val吗?您知道什么是局部变量以及它们如何与每个线程的堆栈相关吗?
- @阿曼奇哈布拉很抱歉这是我的错。我已经改正了密码。
- @是的,没错。我知道什么是局部变量,但不知道它们如何与每个线程的堆栈相关。请解释一下。
- stackoverflow.com/questions/12825847/&hellip;
- @多谢你。非常有用。现在,如果我在函数外部(即类内部)定义了一个变量,那么它也将被共享,或者将被分配到一个单独的线程框架上。
- 你的问题的答案是与索提里奥斯有关的问题,比如这个问题。
除了只有一个servlet实例之外,每个HTTP请求都在一个线程内执行,因此每个doget的执行都有自己的调用堆栈。以下命令在该堆栈上创建局部变量:
1
| String a =request. getParameter("val"); |
因此,对于每个线程都有一个调用堆栈,所以每个线程都有它自己的变量版本。
- 好吧。如果我在函数外部,也就是在类内部定义一个变量,会怎么样呢?这个变量还会被共享吗?
- @很明显,因为是单件的。
- @那么,Mengelle每个线程都会得到它自己的类变量副本吗?尽管不是本地的!.
- 每个thead将引用相同的servlet实例。因此,如果存在一个类属性(范围是实例),那么它将是并发操作。没有"副本"。
现在你已经纠正了代码。对于每个请求,您都在更新将由最新请求更新的val属性值:
1
| String val = request. getParameter("val"); |
So, if you want to retain the value ensure you are increasing the
scope of this variable to class, make it volatile and then while assigning you are verifying if it has any existing value in it.
- 对不起,但不是我想问的。我的意思是问,因为servlet只有一个实例,因此只有一个val变量实例,所以不同的用户如何能够根据他们的请求访问val。基本上,尽管只有一个实例,VAL如何存储不同的值。
- VAL将不具有单个实例,因为它的作用域在函数中。因此,每当调用该函数时,都将创建一个新的val属性实例。
- 另外,如果您将val的范围增加到类,那么对于不同的请求,它可以有不同的值,因为对于每个请求,您都在更新val的值。因此,如果您在类中定义了val而不是函数,然后在分配值时检查它是否有任何现有值,那么对于所有请求,它都将具有相同的值。
我不确定您的代码:没有定义VAL?你在哪里运行这些代码行?
假设VAL为:
1
| String val =request. getParameter("val"); |
你的方法是:
1 2 3
| public void doStuff(HttpRequest request){
...
} |
每个调用都有一个唯一的请求作为参数,因此是一个唯一的"val"参数。