zoukankan      html  css  js  c++  java
  • servlet生命周期和线程安全

      要想写一个servlet,可以继承GenericServlet或者可以继承HttpServlet,或者可以实现servlet接口,但是现在我们大多数网站都是http协议,而且httpservlet是继承自GenericServlet有很多重写的方法,所以现在我们只需要继承httpservlet就可以。

       servlet的生命周期分为三个阶段:

        1.初始化阶段,调用init()方法

        2.响应客户端请求,调用service()方法

        3.终止阶段,调用destroy()方法

      上面是一个servlet整个生命周期,整个的周期都不是我们程序员来调用或者说管理的,那么不是我们来调用的,是由谁来管理调用的?这里的是由web服务器来做的事情,当客户端请求一个servlet,这时服务器会为这个客户端初始化一个servlet,注意,这里是第一次访问,如果是第二次访问那么服务器会直接调用,不会在创建,那么服务器收到这个请求,根据资源地址对应到响应的servlet,这时服务器会调用当前servlet的service方法,来处理这个请求,处理完成后,响应给客户端。

      当一个servlet被创建,这个servlet会在服务器停止的时候被销毁。

      *************************************************

      servlet的线程安全:

      所谓的线程安全,就是多个线程同时或者共同访问同一个资源,这是会有线程安全的问题。

      代码实例:

     1 public class ServletDemo1 extends HttpServlet {
     2     int i = 0;
     3     @Override
     4     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
     5             throws ServletException, IOException {
     6         i++;
     7         try {
     8             Thread.sleep(1000*4);
     9         } catch (InterruptedException e) {
    10             e.printStackTrace();
    11         }
    12         resp.getOutputStream().write((i+"").getBytes());
    13     }
    14     @Override
    15     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    16             throws ServletException, IOException {
    17         doGet(req, resp);
    18     }
    19 }

      上面这样写的话,给一个场景,有两个用户来访问,第一个用户开始访问,第二个紧接着访问,正常来说第一个用户应该得到的是1,但是这里却得到的是2,这里就是一个进程安全,那么这个怎么解决呢,有一个同步代码块,我们就把可能会出现线程安全的代码放在这个同步代码块里面,就可以避免这样的问题,

      

     1     int i = 0;
     2     @Override
     3     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
     4             throws ServletException, IOException {
     5         synchronized (this) {
     6             i++;
     7             try {
     8                 Thread.sleep(1000*4);
     9             } catch (InterruptedException e) {
    10                 e.printStackTrace();
    11             }
    12             resp.getOutputStream().write((i+"").getBytes());
    13         }
    14         
    15     }

      这样就能解决线程安全问题,但是这个synchronized同步代码块执行的原理是,第一个用户请求完成了,我才去解决第二个请求,这个能把人逼疯啊,

      还有一个方法能决绝但是,这个过时了,不提倡试用,就是你这个servlet实现标记接口SingleThreadModel类,这个类里面什么都没有,空接口,这样的接口我们称之为标记接口。

     1 public class ServletDemo1 extends HttpServlet implements SingleThreadModel{
     2     int i = 0;
     3     @Override
     4     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
     5             throws ServletException, IOException {
     6         i++;
     7         try {
     8             Thread.sleep(1000*4);
     9         } catch (InterruptedException e) {
    10             e.printStackTrace();
    11         }
    12         resp.getOutputStream().write((i+"").getBytes());
    13     }
    14     @Override
    15     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    16             throws ServletException, IOException {
    17         doGet(req, resp);
    18     }
    19 }
    如果有使用请标明来源:http://www.cnblogs.com/duwenlei/
  • 相关阅读:
    完美解决HTML5无法上传大文件方法
    完美解决jquery无法上传大文件方法
    Word图片上传控件+整合富文本
    ckeditor粘贴word文档图片的讨论
    python之理解super及MRO列表 ( 示例版 )
    JavaXXX成长直通车_汇总
    P75 验证码识别原理分析
    P74 复习
    P73 卷积神经网络识别手写数字
    P71 激活层与池化层
  • 原文地址:https://www.cnblogs.com/duwenlei/p/3487582.html
Copyright © 2011-2022 走看看