首页 > 作文

Servlet的线程安全问题

更新时间:2023-04-05 01:10:18 阅读: 评论:0

目录
引入rvlet的多线程机制如何修复1.实现 singlethreadmodel 接口2.避免使用成员变量3.同步对共享数据的操作思考与小结参考文章

引入

首先看看这样的代码,有什么问题

这里既要求cmd不能包含calculator又必须要包含calculator,能做到吗,当然是可以的

rvlet的多线程机制

rvlet实际上是一个单件,当我们第一次请求某个rvlet时,rvlet容器将会根据web.xml配置文件或者是注解实例化这个rvlet类,之后如果又有新的客户端请求该rvlet时,则一般不会再实例化该rvlet类,这说明了什么呢?简单来说,当多个用户一起访问时,得到的其实是同一个rv工作展望怎么写let实例,这样的话,他们对实例的成员变量的修改其实会影响到别人,所以在开发的时候如果没有注意这个问题往往会有一些额安全问题,而往往rvlet的线程安全问题主要是由于实例变量使用不当而引起

因此我们再看上面的代码,很明显我们看到了这个status状态变量是实例变量,当然这里为了突出并发的效果,这里加了一个延时,这里简简单单用python实现竞争,也不必上多线程了简单点

url = "http://127.0.0.1:8080/?cmd=open -na calculator"while 1:    r = requests.get(url)    if "cal" in r.text:        print(r.text)
url = "http://127.0.0.1:8080/?cmd=ls"while 1:    r = requests.get(url)

如何修复

1.实现 singlethreadmodel 接口

该接口指定了系统如何处理对同一个rvlet的调用。如果一个rvlet被这个接口指定,那么在这个rvlet中的rvice方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要继承这个接口就行了,因此将我们上面的代码改为

public class testrvlet extends httprvlet implements singlethreadmodel 

这样你觉得就完全安全了吗??答案也不是,如果我们将上面的对状态的定义加上static呢

public st韩语四级atic boolean status;

lol,还是可以成功,原因是singlethreadmodel不会解决所有的线程安全隐患。会话属性和静态变量仍然可以被多线程的多请求同时访问

还有一点很重要该接口在rvlet api 2.4中将不推荐使用。

2.避免使用成员变量

既然问题出自成员变量,那么我们就尽量避免去使用它

将上面的代码改为

public class testrvlet extends httprvlet{//    public  boolean status;    @override    protected void doget(httprvletrequest req, httprvletrespon resp)            th关于春天的歌曲rows rvletexception, ioexception {        boolean status = true;        string cmd = req.getparameter("cmd");        if (cmd.contains("calculator")) {            status = fal;            try {                thread.sleep(1000);            }catch (exception e){            }        }        if (!status) {            return;        }        if (cmd.contains("calculator")){            resp.getwriter().write(cmd);        }    }}

3.同步对共享数据的操作

使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,因此可以将代码写为

public class testrvlet extends httprvlet{    public  boolean status;    @override    protected void doget(httprvletr几何是什么意思equest req, httprvletrespon resp)            throws rvletexception, ioexception {        string cmd = req.getparameter("cmd");        boolean status;        synchronized(this) {            status = true;            if (cmd.contains("calculator")) {                status = fal;                try {                    thread.sleep(5000);                } catch (exception e) {                }            }        }        if (!status) {            return;        }        if (cmd.contains("calculator")){            resp.getwriter().write(cmd);      自编寓言故事  }    }}

思考与小结

但是如果利用上面三种方式去修复,这样就完全没问题了吗?并不是

比如实现singlethreadmodel以及在程序中使用同步来保护要使用的共享的数据,在实际业务当中这也会使得我们系统的性能大大下降,这也是我们不太希望看到的,前者为每个新的请求创建一个单独的rvlet实例,这将引起大量的系统开销,而后者被同步的代码块在同一时刻也只能有一个线程执行它,这也会导致在高并发的情况下,同时处理请求的吞吐量显著的降低

因此,在rlet中避免使用实例变量或许是更好的选择,但如果无法避免,但如果无法避免,也应该尽量做到去同步可用性最小的代码路径

参考文章

/d/file/titlepic/5052426.html 的文章就介绍到这了,更多相关rvlet 线程安全 内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-05 01:10:13,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/854e3e3ec89e65edded2f0f3c039a932.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Servlet的线程安全问题.doc

本文 PDF 下载地址:Servlet的线程安全问题.pdf

标签:线程   变量   实例   代码
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图