Servelet多线程安全问题

原因

一个servlet被实例化一次,当有多个用户访问时,多个线程会访问同一个实例,实例变量就会被不同的用户修改。

简单的案例

新建servlet,访问http://localhost:8080/serverlet/servlert1?u=aaa,即可看到aaa输出

public class servlert1 extends HttpServlet {
    String username;   //实例变量username
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        username=request.getParameter("u");

        //睡眠5s,模拟多并发访问
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //输出u接收到的参数
        response.getOutputStream().write((username).getBytes());
    }
}
A访问http://localhost:8080/serverlet/servlert1?u=aaa
B立马访问http://localhost:8080/serverlet/servlert1?u=bbb

A输出bbb(A的数据被B修改了),B也输出BBB

解决

避免实例变量

public class servlert1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         String username;
        username=request.getParameter("u");

        //睡眠5s,模拟多并发访问
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //输出u接收到的参数
        response.getOutputStream().write((username).getBytes());
    }
}

Servlet 实现SingleThreadModel接口

public class servlert1 extends HttpServlet implements SingleThreadModel{
    String username;   //实例变量username
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        username=request.getParameter("u");

        //睡眠5s,模拟多并发访问
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //输出u接收到的参数
        response.getOutputStream().write((username).getBytes());
    }
}

同步化

public class servlert1 extends HttpServlet {
    String username;   //实例变量username
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //同步访问
        synchronized (this) {
        username=request.getParameter("u");
        //睡眠5s,模拟多并发访问
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //输出u接收到的参数
        response.getOutputStream().write((username).getBytes());
        }
    }
}

最新文章

  1. 在centos7上安装Jenkins
  2. php缓存技术(减少数据库服务器压力)
  3. POJ - 3652 Persistent Bits
  4. XUnit的使用
  5. 算法篇——Cantor的数表
  6. 配置Redis主从复制
  7. libogg.so fro android编译方法
  8. JSLink to render the list to show people detail info with picture
  9. CSU 1337(费马大定理)
  10. 替代 yunio , 推荐一个国外的云存储(同步盘) wuala(这个网站也挂了)——功能评测非常全面
  11. Java学习之自定义异常
  12. hdu Jungle Roads(最小生成树)
  13. 使用CATransformLayer制作3D图像和动画
  14. 深入理解JVM(七)——性能监控工具
  15. 克鲁斯卡尔(Kruskal)算法求最小生成树
  16. textarea的不可拉伸和不可编辑
  17. iOS 中如何判断当前是2G/3G/4G/5G/WiFi
  18. php 把数组保存为标准的数组格式,存储到文件中
  19. docker 的使用
  20. jquery $.each()遍历json数组

热门文章

  1. 关于微信小程序获取多个formId的实现方法
  2. 【SQL server】SQL server基础(一)
  3. pycharm2017.3版本永久激活
  4. css中 禁止spa有点击状态
  5. SQL SERVER 2008 数据库隔离级别代码演示
  6. 02-命令篇——基础命令&常用命令
  7. python 获取指定字符前面或后面的所有字符
  8. ansible的安装和简单使用
  9. 02 | 日志系统:一条SQL更新语句是如何执行的?
  10. vue-ckeditor-word粘贴