本文属于转载:http://www.cnblogs.com/itTeacher/archive/2012/11/14/2769822.html
这个问题,在网上没有看到一个确切的答案,所以我们来分析一下:
首先什么是线程安全?
引用概念:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
那么我们都知道servlet是多线程的,同时一个servlet实现类只会有一个实例对象,也就是它是Singleton的,所以多个线程是可能会访问同一个servlet实例对象的。
每个线程都会为数据实例对象开辟单独的引用,那么servlet会是线程安全的吗?
要判断是否是线程安全,我们需要知道线程安全问题是由什么引起的。
搜索得到答案:线程安全问题都是由全局变量及静态变量引起的。
看到这个答案,突然想起很多年前调查过的一个bug, 那时我们系统中遗留的代码中写了很多全局变量,有一次发布后,客户反馈,当有多人同时进行某个操作时,我们的数据出了问题,那时我们调查后的结果就是:多人同步操作时,有些全局变量的值不对了,之后我们专门设一个人花了很多工夫来将所有全局变量都改成了局部变量了,并且项目要求以后不允许用全局变量。原来那时侯我就已经碰到过线程不安全的情况了啊,不过处理方式或者不用全局,或者加入同步,若加入同步同时也要考虑一下对程序效率会不会产生影响。
由此可知,servlet是否线程安全是由它的实现来决定的,如果它内部的属性或方法会被多个线程改变,它就是线程不安全的,反之,就是线程安全的。
在网上找到一个例子,如下:
public class TestServlet extends HttpServlet {
private int count = 0;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().println("<HTML><BODY>");
response.getWriter().println(this + " ==> ");
response.getWriter().println(Thread.currentThread() + ": <br>");
for(int i=0;i<5;i++){
response.getWriter().println("count = " + count + "<BR>");
try {
Thread.sleep(1000);
count++;
} catch (Exception e) {
e.printStackTrace();
}
}
response.getWriter().println("</BODY></HTML>");
}
}
当同时打开多个浏览器,输入http://localhost:8080/ServletTest/TestServlet时,他们显示的结果不同,这就说明了对于属性count来说,它是线程不安全的,
为了解决这个问题,将代码重构,如下:
public class TestServlet extends HttpServlet {
private int count = 0;
private String synchronizeStr = "";
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().println("<HTML><BODY>");
response.getWriter().println(this + " ==> ");
response.getWriter().println(Thread.currentThread() + ": <br>");
synchronized (synchronizeStr){
for(int i=0;i<5;i++){
response.getWriter().println("count = " + count + "<BR>");
try {
Thread.sleep(1000);
count++;
} catch (Exception e) {
e.printStackTrace();
}
}
}
response.getWriter().println("</BODY></HTML>");
}
}
分享到:
相关推荐
java serverlet实例 用于课堂演示或练习用
java serverlet实例 在学习serverlet的同学可以下载下来看看
jsp&serverlet api开发文档
Java_tomcat_和serverlet的使用
JSP和Serverlet之间的传值方法。JSP和Serverlet之间的传值方法。
javaWeb系列之serverlet最简单登陆代码,初学者的利器。相关还有Struts1.3最简单登陆代码,Hibernate最简单登陆代码,Struts2最简单登陆代码.
网络基础,serverlet的相关题目,对于基础学习很有帮助哦
jsp+serverlet+oracle的网上订餐系统,适合初学者学习用。可作为一个阶段项目对所学知识点进行一个系统的复习,从而提高综合运用能力
serverlet Json commons-beanutils-1.7.0.jar commons-collections-3.2 .jar commons-lang-2.4.jar commons-logging.jar ezmorph-1.0.6.jar json-lib-2.2.3-jdk15.jar xmlns=...
关于动态网页技术Ajax的开发与应用以及web网页开发Servlet原理及应用。帮助理解Ajax和Serverlet
本程序使用MySQL+JavaBean+serverlet+tomcat6.0 用myeclipse实现
适合大学生期末考试复习的JSP/Serverlet复习资料
这是一份基于javaweb+jsp+serverlet开发的图书管理系统
Flex在myeclipse下如何配置以及用serverlet的交互
JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改JSP serverlet 增删查改
jsp +serverLET+JAVABEAN 学习文件,如果觉的可以就下载吧。
这是我接着上次传的jsp视频,都是来子培训班的东西; 先传2集;有人下载了我传剩下的要不也没什么用
filter__serverlet__listener与interceptor的相同点与区别
在线考试系统,实现了教师,学生,管理员的基本功能
使用J2EE开发的学生成绩管理系统,包括设计文档和数据库详细设计