问题:使用以下的代码演示servlet的线程安全问题?
1 public class MultiThreadQuestion extends HttpServlet {
2 public int count = 0;
3 public void doGet(HttpServletRequest request, HttpServletResponse response)
4 throws ServletException, IOException {
5 // 1. 验证服务器是以线程的方式处理用户请求的
6 try {
7 this.count++;
8 Thread.sleep(5 * 1000);
9 } catch (InterruptedException e) {
10 e.printStackTrace();
11 }
12 response.getOutputStream().write(("线程名:"+Thread.currentThread().getName()+"count="+this. count).getBytes());
13 }
14 }
同时访问以上的代码发现三次同时出现3,这就是线程的并发访问的问题。
解决方案就是:同步
给访问共享资源的代码加锁。
1 public class MultiThreadQuestion extends HttpServlet {
2 public int count = 0;
3 public void doGet(HttpServletRequest request, HttpServletResponse response)
4 throws ServletException, IOException {
5 // 1. 验证服务器是以线程的方式处理用户请求的
6 synchronized (this) {
7 try {
8 this.count++;
9 Thread.sleep(5 * 1000);
10 } catch (InterruptedException e) {
11 e.printStackTrace();
12 }
13 response.getOutputStream().write(("线程名:"+Thread.currentThread().getName()+"count="+this.count).getBytes());
14 }
15 }
16 }
总结:
1.如果直接使用同步关键字,那么会导致servlet的运行效率严重的降低。
2.尽量避免使用servlet的成员变量。
3.如果避免不了那么我们就需要使用线程安全的成员变量。
ArrayList
Vector HashSet
如果需要不是线程安全的集合可以使用Collections进行线程安全的转换
4.ServletContext、HttpSession需要使用的时候一定要使用同步。
5.在servlet中最好使用局部变量。
时间: 2024-11-08 15:03:45