← 返回首页
Servlet基础教程(九)
发表时间:2020-04-06 01:49:05
讲解Servlet如何处理请求

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采取单例多线程的方式处理客户端的请求。由于是多线程,所以存在线程安全问题。