![](/img/trans.png)
[英]Servlet seems to handle multiple concurrent browser requests synchronously
[英]Concurrent servlet requests overwrites static values
我已经部署了一个使用servlet的简单Java Web应用程序。 我面临并发请求的问题。
示例程序:
Public Class Test {
static int num;
public Test(){
}
public void setVal{
Date dd = new Date();
this.num = dd.getTime.toString()
}
public int getVal {
return this.num;
}
}
Public Class Print {
Function generateID{
Test test = new Test();
test.setVal();
Thread.sleep(10000);
System.out.print(test.getVal() );
}
}
假设Request1从类Print调用了generateID。 当请求1睡眠10秒钟时,请求2出现并调用相同的函数generateID。 函数setVal()将覆盖num的值。 同时,请求1打印num的覆盖值。
我如何使这些请求彼此独立并且彼此不重叠。我不想使用同步,因为实际程序为每个请求运行一个小时以上,因此我无法锁定该函数。 此外,除了使用会话之外,还有其他任何方法。
作为Sotirios Delimanolis
在他的评论中说,你应该使用锁的线程synchronized
在java中的关键字。
同步方法提供了一种防止线程干扰和内存一致性错误的简单策略:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都将通过同步方法完成。
public void synchronized generateID{
Test test = new Test();
test.setVal();
Thread.sleep(10000);
System.out.print(test.getVal() );
}
您需要设计您的应用程序,以便原子操作本质上花费的时间尽可能少。
在您的情况下,您将在Test
类中创建另一个同步的 setGetVall()
方法:
public int synchronized setGetVal() {
setVal();
return getVal()
}
那么你将有
public void generateID() {
Test test = new Test();
int final newValue = test.setGetVal();
Thread.sleep(10000); // and now it can safely sleep as long as it wants
System.out.print( newValue );
}
对于更复杂的情况,您将需要更复杂的锁定 ,但是原理保持不变。
我建议您看一下ThreadLocal,它提供了在线程内创建局部变量的特权。 链接在这里。 希望这可以解决您的问题。
http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html
Servlet并不具有您不希望在多个线程,周期之间使用的实例变量。 任何时候都存在单个servlet的单个实例。 对Servlet的每个请求都在其自己的堆栈,线程中执行,但是只有一个servlet实例。
同步访问该实例变量只会在您的应用程序中造成瓶颈。 不要做
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.