servlet线程安全问题
2015-07-09 00:00
344 查看
线程安全网上是这么解释的:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
产生原因:全局变量及静态变量未受控制的访问。
servlet是否线程安全实质就是多线程线程安全问题,servlet单例多线程访问模式下,是否线程安全看具体实现,谈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>");
}
}
产生原因:全局变量及静态变量未受控制的访问。
servlet是否线程安全实质就是多线程线程安全问题,servlet单例多线程访问模式下,是否线程安全看具体实现,谈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>");
}
}
相关文章推荐
- 基础学习的重要性
- python
- js
- python
- python
- python 3.x和2.x区别
- 一个程序员对互联网的思考
- XML和JavaBean之间的互转---XStream
- VIEWGOOD(远古)建立区域性教育资源公共平台的解决方案
- canvas时钟
- NFS
- Android 动画之TranslateAnimation应用详解
- 潍坊OA发展点在哪?
- Fragment之间的参数的传递
- fatfree-f3小型php框架(一)
- android中程序的退出和关闭
- android中的surfaceview控件
- mysql全文索引查询所用关键词最小长度限制
- CentOS环境下yum安装LAMP(Linux+Apache+Mysql+php)
- 手动生成DataTable时遇到的问题(已解决)