微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

手写tomcat——有线程池化能力的servlet 服务

点击查看代码
public class DiyTomcat {

    private int port = 8080;

    public static final HashMap<String, DiyServlet> SERVLET_MAPPING = new HashMap<>();

    public static final HashMap<String,String> URL_MAPPING = new HashMap<>();

    private static ThreadPoolExecutor threadPoolExecutor;

    static {
        loadServlet();
        initExecutors();
    }

    // 线程池化
    private static void initExecutors() {
        int corePoolSize = 10;
        int maximumPoolSize = 50;
        long keepAliveTime = 100L;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
    }

    private static void loadServlet() {
        try {
            //获取web.xml目录地址
            String path = DiyTomcat.class.getResource("/").getPath();
            SAXReader reader = new SAXReader();
            //读取web.xml文件
            Document document = reader.read(new File(path + "web.xml"));
            //获取标签(servlet和servlet-mapping),放在一个List中
            Element rootElement = document.getRootElement();
            List<Element> elements = rootElement.elements();
            //循环将映射写进map映射里
            for(Element element : elements){
                if ("servlet".equalsIgnoreCase(element.getName())){
                    Element servletName = element.element("servlet-name");
                    Element servletClass = element.element("servlet-class");
                    //需要注意的是servletMapping映射的第二个参数,要通过反射的方式进行实例化
                    SERVLET_MAPPING.put(servletName.getText(),
                            (DiyServlet) Class.forName(servletClass.getText().trim()).newInstance());
                }else if ("servlet-mapping".equalsIgnoreCase(element.getName())){
                    Element servletName = element.element("servlet-name");
                    Element urlPattern = element.element("url-pattern");
                    URL_MAPPING.put(urlPattern.getText(), servletName.getText());
                }
            }
        } catch (DocumentException e) {
            e.printstacktrace();
        } catch (MalformedURLException e) {
            e.printstacktrace();
        } catch (ClassNotFoundException e) {
            e.printstacktrace();
        } catch (illegalaccessexception e) {
            e.printstacktrace();
        } catch (InstantiationException e) {
            e.printstacktrace();
        }
    }

    public void start() throws IOException {
        ServerSocket serverSocket = new ServerSocket(port);
        while (true) {
            Socket socket = serverSocket.accept();
            RequestHandler requestHandler = new RequestHandler(socket);
            // 一个 socket 一个线程
            // new Thread(requestHandler).start();
            // 使用线程组干活
            threadPoolExecutor.execute(requestHandler);
        }
    }
}

  1. 通过initExecutors方法创建出一个线程池
    private static void initExecutors() {
        // 核心线程数
        int corePoolSize = 10;
       // 最大线程数
        int maximumPoolSize = 50;
       // 空闲线程保活时间
        long keepAliveTime = 100L;
       // 保活单位,当前设置为秒
        TimeUnit unit = TimeUnit.SECONDS;
       // 线程池队列
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
       // 线程创建工厂
       ThreadFactory threadFactory = Executors.defaultThreadFactory();
       // 池子满后的拒绝请求处理器
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
    }
  1. accept到socket后直接包装成RequestHandler交由线程池处理
while (true) {
            Socket socket = serverSocket.accept();
            RequestHandler requestHandler = new RequestHandler(socket);
            // 一个 socket 一个线程
            // new Thread(requestHandler).start();
            // 使用线程组干活
            threadPoolExecutor.execute(requestHandler);
        }

代码地址:
https://github.com/ZhongJinHacker/diy-tomcat/tree/pool-tomcat


版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐