servlet线程模型

来源:互联网 发布:彩云数据 编辑:程序博客网 时间:2024/06/18 14:18

   servlet在Javaweb的开发中是必不可少,尽管有SSM这些优秀的框架,尤其是SpringMVC解放了我们写大量的servlet,但是核心原理是基于servlet,DispatchServlet,就是一个servlet,它会拦截所有请求,然后分发。回到正题,servlet在tomcat容器内是怎么样的存在,是当每一次请求,web容器就重新初始化一个servlet实例,还是只存在一个servlet实例,其实在tomcat容器中,servlet的线程模型是单例多线程,就是存在一个实例,每当有一个请求,都会分发一个线程就执行一个servlet实例相应的方法:比如post,get等。这里的线程是重用的,tomcat的容器使用了线程池。我写了一个程序,简单的说明了这一点:  

import java.io.*;import java.net.Socket;/** * Created by Jackie on 2017/9/20. */public class SocketSender {    private static final String REQUES_CONTENT = "GET / HTTP/1.1\r\n" +            "Host: localhost:8080\r\n\r\n"           ;    public static void main(String[] args){        for (int i = 0 ; i < 10 ; i++){            Socket socket;            try {                socket = new Socket("localhost", 8080);                OutputStream outputStream = socket.getOutputStream();                BufferedOutputStream out = new BufferedOutputStream(outputStream);                out.write(REQUES_CONTENT.getBytes());                out.flush();                BufferedReader bf = new BufferedReader(new InputStreamReader(socket.getInputStream()));                String line;                while ((line = bf.readLine()) != null&&!line.isEmpty()){                    System.out.println(line);                }                out.close();                bf.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

package online.fengshan;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * Created by Jackie on 2017/9/20. * */public class ServletDemo extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        System.out.println(Thread.currentThread());    }}

  一个是servlet,另外一个程序就是使用socket发起10个http请求,在servlet中打印执行get方法的当前线程。我们来看看运行结果:

  这是在tomcat控制台中打印的信息,可以看到请求是由不同的线程执行的,但是有些请求是由一个线程执行的,因为使用了线程池,线程可重用。

  既然知道了servlet是单例多线程,那么我们平时写程序要注意什么,因为是单例,所以全局变量在多线程下是线程不安全的,所以有些不能被线程共享的变量尽量不要写在全局中,局部变量可以避免这点,局部变量是线程独有的,在虚拟机栈中为线程独有,不明白的可以去看看JVM内存模型。

原创粉丝点击