关于servlet的线程安全问题

 

IT程序员开发必备-各类资源下载清单,史上最全IT资源,个人收藏总结!



问题:首先哪些情况会出现线程安全问题呢?、

      (1)对于实例变量(非静态的全局变量),如果是多个实例对象,则线程安全;如果是单实例,则线程不安全!如:  

     Servlet.java    

public class ServletDemo1 extends HttpServlet {

    int i = 0;

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

       i++;

      try {

        Thread.sleep(1000*5);

      catch (InterruptedException e) {

      // TODO Auto-generated catch block

          e.printStackTrace();

     }

  PrintWriter out = response.getWriter();

  out.print("This is the doGet method of the ServletDemo1,i = "+i);

}

      由于HttpServlet是单实例,只会被实例化一次,即多个请求共享同一个Servlet,如果Servlet还没有被实例化,则当两个用户同时访问该Servlet(相隔1秒)时,第一个用户打印"i=2",第二个用户也打印"i=2",这里的原因能想明白吧。

    解决办法:

  public class ServletDemo1 extends HttpServlet {

      int i = 0;

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

  synchronized (this) {

     try {

      i++;

        Thread.sleep(1000*5);  

     catch (InterruptedException e) {

         e.printStackTrace();

     }

    PrintWriter out = response.getWriter();

    out.print("This is the doGet method of the ServletDemo1,i = "+i);

  } 

}

  }

      (2)对于类变量(静态变量),即使是实例化多个对象,其类变量也是供所有实例对象所共享,所以线程不安全!如:

   Person.java

public class Person {

  public static int age;

}

   Servlet.java

public class ServletDemo1 extends HttpServlet {

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

      Person person =  new Person();

       person.age++;

      try {

          Thread.sleep(1000*5);

      catch (InterruptedException e) {  

         e.printStackTrace();

      }       

  PrintWriter out = response.getWriter();

  out.print("This is the doGet method of the ServletDemo1,person.age = "+person.age);

}

由于HttpServlet是单实例,只会被实例化一次,即多个请求共享同一个Servlet,如果Servlet还没有被实例化,则当两个用户同时访问该Servlet(相隔1秒)时,第一个用户打印"person.age=2",第二个用户也打印"person.age=2",这里的原因能想明白吧。因为虽然每个请求都会new Person(),然后将age++;他们虽然是两个不同的实例对象,但是age是属于Person类而不属于某一个实例,所以两个对象操作的是同一个age,所以线程不安全,

 解决办法:

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

      Person person = null;  

synchronized (this) {

    try {

          person =  new Person();

          person.age++;  

          Thread.sleep(1000*5);

   catch (InterruptedException e) {

      e.printStackTrace();

    }

   PrintWriter out = response.getWriter();

   out.print("This is the doGet method of the ServletDemo1,person.age = "+person.age);

 

}


                    

 

                       


      

  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值