servlet的一些细节问题(1)
1、一个已经注册的servlet可以被多次映射

2、当映射一个servlet时,访问路径可以多层
<url-pattern>/servlet/MyServlet1/index.html</url-pattern>
从这里也可以看出,后缀名是html不一定就是html,可能是假象
3、同一个servlet可以被映射到多个URL上,可以使用*通配符,但是只能有两种固定格式:
1)一种格式是“*.扩展名”,比如:*.do *.ss
2)一种格式是:以正斜杠/开头,并以“/*”结尾。 比如:
<url-pattern>/*</url-pattern>
<url-pattern>/abc/*</url-pattern>
注:在匹配的时候,要参考的标准:
(1)看谁的匹配度高,谁就被选中
(2)*.do的优先级最低
4、servlet是一个供其他java程序(servlet引擎【web服务器/tomcat】)调用的java类,它不能独立运行,它运行完全由servlet引擎来控制和调度。
servlet的单例问题:
当servlet被第一次访问后,就被加载到内存,为后续的各个请求服务,直至web容器退出/或者reload该web应用,servlet实例对象才会被销毁。即在使用中是单例。


注意:因为servlet是单例,因此会出现线程安全问题,如:售票系统,如果不加同步机制,很有可能出现问题。



简单的解决办法:将if...else...那段代码加锁,即用synchronized包起来
synchronized(this){
if(ticket>0){
System.out.println("你买到票了");
try{
Thread.sleep(10*1000);
}catch(Exception e){
e.printStackTrace();
}
ticket--;
}else{
System.out.println("你买不到票了");
}
}
注意:这里我给大家一个原则:
(1)如果一个变量需要多个用户共享,则应当在访问该变量时,加同步机制
synchronized(对象){
//同步代码
}
(2)如果一个变量不需要共享,则直接在doGet()或者doPost()定义,这样不会存在线程安全问题;
补充:在servlet整个生命周期内,servlet的init方法只被调用一次。而对一个servlet的每次访问请求都导致servlet引擎调用一次servlet的service方法。对于每次访问请求,servlet引擎都会创建一个新的
HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
浙公网安备 33010602011771号