zoukankan      html  css  js  c++  java
  • JavaWeb学习笔记16--Servlet的映射匹配问题、线程安全问题

    欢迎转载,但请保留文章原始出处→_→

    文章来源:http://www.cnblogs.com/smyhvae/p/4140529.html

    一、Servlet映射匹配问题:

    在第一篇文章中的第四段(MyEclipse及Tomcat的配置)已经讲到这个知识,现在再细化一下:

    由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。

    <servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。

    一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。例如:

            <servlet-name>MyServlet</servlet-name>
            <servlet-class>com.vae.servlet.MyServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>/servlet/MyServlet</url-pattern>
        </servlet-mapping>
     

    需要注意的是:

    1、一个<servlet>可以对应多个<serlvet-mapping>,从而一个Servlet可以有多个路径来访问

    2、url-partten中的路径也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。

    由于*的引入,有可能一个路径被多个urlpartten匹配,这是优先级判断条件如下:

    • 哪个越精确找哪个
    • *.后缀的格式永远匹配级最低

    【举例】

    对于如下的一些映射关系:

    • Servlet1 映射到 /abc/*
    • Servlet2 映射到 /*    (表示任何路径都能匹配)
    • Servlet3 映射到 /abc
    • Servlet4 映射到 *.do

    问题:

    • 当请求URL为“/abc/a.html”时,“/abc/*”和“/*”都匹配,哪个servlet响应?Servlet引擎将调用Servlet1。
    • 当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应?Servlet引擎将调用Servlet3。
    • 当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应?Servlet引擎将调用Servlet1。
    • 当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应?Servlet引擎将调用Servlet2。
    • 当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应?Servlet引擎将调用Servlet2。

    3、可以在<serlvet>标签里配置<load-on-startup>可以用来指定启动顺序。Servlet默认是在第一次被访问的时候创建,如果配置了这个标签,就会随着Web应用的启动而创建。举例:

        <servlet>
            <servlet-name>Servlet2</servlet-name>
            <servlet-class>Servlet2</servlet-class>
            <load-on-startup>2</load-on-startup>
        </servlet>

    第4行的int值表示多个serlvet的启动顺序。 

    4、缺省Servlet:

    如果有一个Servlet的url-partten被配置为了一根正斜杠"/",这个Servlet就变成了缺省Serlvet.其他Servlet都不处理的请求,由缺省Servlet来处理.

    其实对于静态资源的访问就是由缺省Servlet来执;设置404页面、500页面等提示页面也是由缺省Servlet来执行。通常我们不会自己去配置缺省Servlet

    二、线程安全问题

    Servlet引擎采用多线程模式运行,它为并发的每个访问请求都使用一个独立的线程来进行响应。

    由于默认情况下Servlet在内存中只有一个对象,当多个浏览器并发访问Servlet时就有可能产生线程安全问题。

    面试题目注意:Servlet线程不安全,自始至终只维护一个实例。

    注:线程安全本质即:同一个资源被多个线程同时操作,可能会互相干扰。  

    解决方案:

    1、SingleThreadModel接口(标记接口,单线程模型接口):不能真的防止线程安全问题(已过时)

    Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用Servlet的service方法。对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用独立的一个Servlet实例对象

    注:此接口在API 2.4中就已经过时,虽然解决了线程安全问题,但是消耗了大量性能(不同的客户端同时访问会创建不同的Servlet实例),所以此方法建议不用,实际开发中也不用。

    2、使用同步代码块:效率降低

    下列需要考虑线程安全问题:(多个线程同时访问数据时)

    • 访问成员变量时(所以,在Servlet中定义成员变量时,需要考虑线程安全问题) 
    • 访问共享资源时

    注:Servlet中尽量不要使用成员变量。

    代码举例:访问成员变量时,要考虑线程安全问题

     
     1 public class MyServlet1 extends HttpServlet {
     2     private static final long serialVersionUID = 1L;
     3     
     4     public int count = 10;// 在Servlet中定义成员变量,需要考虑线程安全问题     
     5        
     6     public MyServlet1() {
     7         super();
     8     }
     9  
    10     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    11         doPost(request, response);
    12     }
    13  
    14     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    15     
    16         synchronized (this) {
    17             count ++;
    18         }
    19     }
    20  
    21 }
     

    最终解决方案:在Servlet中尽量少用类变量(成员变量),如果一定要用类变量则用锁来防止线程安全问题,但是要注意锁住内容应该是造成线程安全问题的核心代码,尽量的少锁主内容,减少等待时间提高servlet的响应速度。

  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/huangyangquan/p/8999982.html
Copyright © 2011-2022 走看看