Java Web-Servlet线程问题

什么情况下会存在线程安全问题?

条件1:多线程并发
条件2:有共享数据
条件3:共享数据涉及到修改操作

怎么解决线程安全问题?

选择1:使用局部变量
选择2:使用线程同步机制synchronized

JVM包括三块主要的内存空间:栈内存、堆内存(共享数据)、方法区内存(共享数据)

Servlet的多线程机制
 
  Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。Servlet容器会自动使用线程池等技术来支持系统的运行,

​ 这样,当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致。

  public class ConcurrentTest extends HttpServlet {
      PrintWriter output;
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
         String  username;
          response.setContentType("text/html;charset=gb2312");
          username=request.getParameter("username");
          output=response.getWriter();
         try {
            Thread.sleep(5000);            //为了突出并发问题,在这设置一个延时
             output.println("用户名:"+username+"<BR>"); 
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 }

该Servlet中定义了一个实例变量output,在service方法将其赋值为用户的输出。当一个用户访问该Servlet时,程序会正常的运行,但当多个用户并发访问时,就可能会出现其它用户的信息显示在另外一些用户的浏览器上的问题。这是一个严重的问题。

1、实现 SingleThreadModel 接口

该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要将前面的Concurrent Test类的类头定义更改为

public class ConcurrentTest extends HttpServlet implements SingleThreadModel 

2、同步对共享数据的操作

使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。同步后的代码如下:

 public class ConcurrentTest extends HttpServlet {
     PrintWriter output;
     @Override
     protected void service(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         String  username;
         response.setContentType("text/html;charset=gb2312");
         username=request.getParameter("username");
         synchronized(this){
             output=response.getWriter();
             try {
                 Thread.sleep(5000);//为了突出并发问题,在这设置一个延时
                 output.println("用户名:"+username+"<BR>"); 
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值