繁体   English   中英

并发servlet请求覆盖静态值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM