Servlet线程安全性

问题:使用以下的代码演示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中最好使用局部变量。

你可能感兴趣的:(servlet)