• Servlet(2)


    一、伪代码演示Tomcat的内部代码运行

    1)、通过映射找到servlet-class的内容,字符串:com.gqx.servlet.FirstServlet

    2)、通过反射构造构造FirstServlet对象

      2、1 得到字节码(class)文件对象

      Class clazz=class.forName("com.gqx.servlet.FirstServlet");

      2、2调用无参的构造方法来构造对象

      Object obj =clazz.newInstance();  -->serlvet的构造方法被激活

    3)、创建ServletConfig对象,通过反射调用init方法

       3.1 得到方法对象

                      Method m = clazz.getDeclareMethod("init",ServletConfig.class);

              3.2 调用方法

                      m.invoke(obj,config);             --2.servlet的init方法被调用

    4)创建request,response对象,通过反射调用service方法

              4.1 得到方法对象

                      Methodm m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);

               4.2 调用方法

          m.invoke(obj,request,response);  --3.servlet的service方法被调用  

     5)当tomcat服务器停止或web应用重新部署,通过反射调用destroy方法

               5.1 得到方法对象

                      Method m = clazz.getDeclareMethod("destroy",null);

                5.2 调用方法

                      m.invoke(obj,null);            --4.servlet的destroy方法被调用

    用时序图来演示servlet的生命周期

    Servlet的自动加载

      默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。         改变servlet创建对象的时机: 提前到加载web应用的时候!!!

             在servlet的配置信息中,加上一个<load-on-startup>即可!!

    如下

    复制代码
    <servlet>
    
        <servlet-name>LifeDemo</servlet-name>
    
        <servlet-class>gz.itcast.c_life.LifeDemo</servlet-class>
    
        <!-- 让servlet对象自动加载 -->
    
        <load-on-startup>1</load-on-startup> 
    <!-- 注意: 整数值越大,创建优先级越低!!-->
    
      </servlet>
    复制代码

    有参的init方法和无参的init方法

      有参的init方法中实现了无参的init方法,其源代码中调用了this.init();所以我们一般都会在无参的init方法中写入代码

    Servlet的多线程并发问题

      

    注意: servlet对象在tomcat服务器是单实例多线程的。

    因为servlet是多线程的,所以当多个servlet的线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。

     

    解决办法:

             1)把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)

             2)建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致并发效率降低。

    实例代码如下:

    复制代码
    package com.gqxing.servlet2;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ThreadDemo extends HttpServlet {
        
        /**
         * 多线程安全问题
         * 案例:访问网站的第几个人数
         */
        int count=1;
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("你现在是当前网站的第"+count+"个访客!");
            //为了效果,这里用sleep方法去让线程同步
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //当多个线程同时访问这里获取相同的count值的时候会发生线程安全问题。
            count++;
        }
    
    }
    复制代码

    效果如图

    这个时候要加入避免出现线程安全的机制

    复制代码
    package com.gqxing.servlet2;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ThreadDemo2 extends HttpServlet {
        
        /**
         * 多线程安全问题
         * 案例:访问网站的第几个人数
         */
        int count=1;
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            //为当前访问的线程加锁,
            synchronized (ThreadDemo2.class) {//锁线程必须是唯一的,可以用当前的字节码对象
                response.getWriter().write("你现在是当前网站的第"+count+"个访客!");
            }    
            count++;
        }
    
    }
    复制代码
  • 相关阅读:
    Omi新成员omi-router正式发布
    Omi架构与React Fiber
    Omi框架Store体系的前世今生
    Omi v1.0震撼发布
    omi-cli新版发布-升级webpack2和支持sass生成组件局部CSS
    Omi应用md2site-0.5.0发布-支持动态markdown拉取解析
    Omi应用md2site发布-markdown转网站利器
    AlloyTouch之无限循环select插件
    Omi教程-插件体系
    AlloyTouch之select选择插件
  • 原文地址:https://www.cnblogs.com/zhangyubao/p/6973775.html
Copyright © 2020-2023  润新知