Servlet采取单例多线程的方式处理客户端的请求。
1.如何体现单例
每个Servlet实例对象在服务器中仅仅有一份,也就是单例的。 如果Servlet没有重写父类的hashCode方法,那么不同的Servlet实例的hashCode应该不同。如果是单例的,那么hashCode应该相同。
例如: 改写上节的servlet,让doGet与doPost执行相同的动作。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//System.out.println("执行了doGet...");
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行了doPost...");
System.out.println("servlet对象的hashCode:"+this.hashCode());
}
启动两个不同的浏览器点击超链接,来表示两个不同的客户端的请求。测试结果发现hashCode完全相同。
执行了构造方法...
执行了init(config)方法...
执行了service()...
执行了doPost...
servlet对象的hashCode:1738566730
执行了service()...
执行了doPost...
servlet对象的hashCode:1738566730
2.如何体现多线程
我们在doPost方法中,打印当前线程的编号。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//System.out.println("执行了doGet...");
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行了doPost...");
System.out.println("servlet对象的hashCode:"+this.hashCode());
System.out.println("当前线程ID:"+Thread.currentThread().getId());
}
启动两个不同的浏览器点击超链接,来表示两个不同的客户端的请求。测试结果发现hashCode完全相同,但是线程编号不同。
执行了构造方法...
执行了init(config)方法...
执行了service()...
执行了doPost...
servlet对象的hashCode:1478700803
当前线程ID:29
执行了service()...
执行了doPost...
servlet对象的hashCode:1478700803
当前线程ID:30
小结:
Servlet采取单例多线程的方式处理客户端的请求。由于是多线程,所以存在线程安全问题。