servlet的自动加载:
默认情况下,第一次访问servlet的时候创建servlet对象,如果servlet的构造方法或initial方法中执行了比较多的逻辑代码,那么导致用户第一次访问servlet的时候比较慢。
改变servlet创建对象的时候,提前到加载web应用的时候。
在servlet的配置信息中,加上一个<load-on-startup>即可。
1 <servlet> 2 <servlet-name>Demo1</servlet-name> 3 <servlet-class>com.maodoer.test.Demo1</servlet-class> 4 <!-- 让servlet对象自动加载 --> 5 <load-on-startup>1</load-on-startup> 6 </servlet>
这样就可以在tomcat服务器启动的时候就会创建Servlet对象。
<load-on-startup>中,数值越大,优先级越低。
initial方法
1 /** 2 * 有参数的init方法和无参数的init方法 3 * @author MaoDoer 4 * 5 */ 6 public class InitDemo extends HttpServlet { 7 8 /** 9 * 有参数的init方法 10 * 该方法是Servlet的生命周期方法,一定会被tomcat服务器调用 11 */ 12 /** 13 * 注意:如果要编写初始化代码,不需要覆盖有参数的init方法 14 */ 15 /* @Override 16 public void init(ServletConfig config) throws ServletException { 17 System.out.println("有参数的init方法"); 18 }*/ 19 20 /** 21 * 无参数的init方法 22 * 该方法是servlet的编写初始化代码的方法。是Sun公司设计出来专门 23 * 给开发者进行覆盖,然后在里卖弄编写servlet的初始逻辑代码的方法 24 */ 25 @Override 26 public void init() throws ServletException { 27 System.out.println("无参数的init方法"); 28 } 29 }
Servlet对象在tomcat服务器中是单实例多线程的。
1 public class ThreadDemo extends HttpServlet{ 2 int count=1; 3 @Override 4 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 5 resp.setContentType("text/html;charset=utf-8"); 6 synchronized(ThreadDemo.class){ 7 resp.getWriter().write("你现在是该网站的第"+count+"个访客");//线程1 8 //线程1还没有执行count++,线程2就开始执行 9 /*try { 10 Thread.sleep(5000); 11 } catch (InterruptedException e) { 12 e.printStackTrace(); 13 }*/ 14 count++; 15 } 16 } 17 }
Servlet的多线程并发问题:
因为servlet是多线程的,所以当多个servlet的线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。
解决办法:
1.把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)
2.建议在servlet类中尽量不要使用成员变量。如果确实要使用成员变量,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里),一笔秒因为同步而导致并发效率降低。