Servlet的线程安全问题

前言

当有多个客户端同时访问同一个Servlet资源时,Web服务器就会为每一个客户端创建一个线程,并且调用service(..)方法,如果同时访问了service(..)方法中的共享资源,就可能会引发线程安全问题。

代码模拟线程安全

    public class Demo7 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    //外部共享资源num
    int num = 0;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        num++;

        //为了模拟多线程同时访问,调用sleep()方法让当前线程休眠一会
        try {
            Thread.sleep(1000*3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        response.getOutputStream().write(("num is :     "+num).getBytes());
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

打开浏览器,同时打开两个窗口,同时访问Demo7这个servlet,比如A对此资源进行了访问,A应该得到的结果是num=1;这时,B线程进来了,A线程休眠未结束,而此时的num已经被A修改为1,B继续修改,此时num=2,所以当A休眠结束,得到的结果变成了A得到的num=2;这就引发了线程安全问题;

解决方案一

加上synchronized关键字

        //加上synchronized关键字,锁定当前线程
        synchronized(this){
            try {
                num++;
                Thread.sleep(1000*3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            response.getOutputStream().write(("num is :     "+num).getBytes());
        }

对线程进行锁定可以暂时解决这个问题,但是这对性能就有了影响,当A访问时,B就要在外面等着A结束才能访问;

解决方案二

    public class Demo8 extends HttpServlet implements SingleThreadModel
    //此接口已经被标记为过时

实现SingeleThreadModel接口,这个接口中没有定义任何方法,就如同Cloneable 、Serializable这些接口一样,都属于一种标记接口,当实现这个接口,就会每一个线程创建一个servlet对象,所以AB同时访问时,A有一个自己的servlet对象,B有一个自己的servlet对象,线程安全就解决了,但是,这也不是最好的解决方案,因为解决线程安全最好的方式是解决一个servlet对象被多个线程同时访问;就是struts2中,每一个Action都是设置为prototype类型,就是避免了线程安全问题

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值