当前位置: 技术问答>java相关
关于jsp线程安全的问题
来源: 互联网 发布时间:2015-10-18
本文导语: 看到一篇帖子,说了一个jsp线程不安全的问题,然后提出了一种将实例变量变成局部变量的方式,不是太明白。贴出来和大家讨论一下。 上面的程序模拟网上购物中的一部分,把用户在浏览器中输入的用...
看到一篇帖子,说了一个jsp线程不安全的问题,然后提出了一种将实例变量变成局部变量的方式,不是太明白。贴出来和大家讨论一下。
上面的程序模拟网上购物中的一部分,把用户在浏览器中输入的用户名,购买的物品名称,数量保存到表BUY中。在savebuy()函数中用到了实例变量,所以它不是线程安全的.因为:程序中的每一条语句都不是原子操作,如name=request.getParameter("name");在执行是会对应多个机器指令,在任何时候都可能因系统调度而转入睡眠状态,让其他的线程继续执行.如果线程A在执行到(1)的时候转入睡眠状态,线程B开始执行并改变QUANTITY的值,那么当又到A执行时,它会从调用savebuy()函数开始执行,这样它保存到表中的QUANTITY是被线程B改过的值,那么线程A对应的用户所实际购买的数量与保持到表中的数据不一致.这是个很严重的问题.
三、解决方法
(3)采用局部变量代替实例变量,函数savebuy()声明如下:
因为在savebuy()中使用的是传给他的形参,是在堆栈中分配的,所以是线程安全的.
public void savebuy(String name,String product, int quantity)
{
......
}
调用方式改为:
**************************************************************************
以上为帖子的大致内容,我不明白的地方是:
如果在/* (2) */ 发生作者所说的问题,那不也是不对的吗?
上面的程序模拟网上购物中的一部分,把用户在浏览器中输入的用户名,购买的物品名称,数量保存到表BUY中。在savebuy()函数中用到了实例变量,所以它不是线程安全的.因为:程序中的每一条语句都不是原子操作,如name=request.getParameter("name");在执行是会对应多个机器指令,在任何时候都可能因系统调度而转入睡眠状态,让其他的线程继续执行.如果线程A在执行到(1)的时候转入睡眠状态,线程B开始执行并改变QUANTITY的值,那么当又到A执行时,它会从调用savebuy()函数开始执行,这样它保存到表中的QUANTITY是被线程B改过的值,那么线程A对应的用户所实际购买的数量与保持到表中的数据不一致.这是个很严重的问题.
三、解决方法
(3)采用局部变量代替实例变量,函数savebuy()声明如下:
因为在savebuy()中使用的是传给他的形参,是在堆栈中分配的,所以是线程安全的.
public void savebuy(String name,String product, int quantity)
{
......
}
调用方式改为:
**************************************************************************
以上为帖子的大致内容,我不明白的地方是:
如果在/* (2) */ 发生作者所说的问题,那不也是不对的吗?
|
/* (2) */ 是从request获取,
一个servlet线程是在用户发送request创建,每个线程都对应不同的request,而/* (2) */取的值正是放在request中,所以是局部的;其实问题最关键点在于,不应该在jsp中写方法。
一个servlet线程是在用户发送request创建,每个线程都对应不同的request,而/* (2) */取的值正是放在request中,所以是局部的;其实问题最关键点在于,不应该在jsp中写方法。
|
1、jsp运行前要编译成servlet, 而servlet是class
2、并发访问同一个jsp时,webserver上有多个线程同时执行同一个jsp(class)实例。这样会造成成员变量的互相篡改,从而导致错误。
3、局部变量在每个线程中构造,就是说有几个并发访问就有几套局部变量的实例。
4、这不仅是jsp或servlet的问题,所有多线程程序都要考虑同步的问题。
2、并发访问同一个jsp时,webserver上有多个线程同时执行同一个jsp(class)实例。这样会造成成员变量的互相篡改,从而导致错误。
3、局部变量在每个线程中构造,就是说有几个并发访问就有几套局部变量的实例。
4、这不仅是jsp或servlet的问题,所有多线程程序都要考虑同步的问题。