手写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);
        }
    }
}
- 通过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
        );
    }
- 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
手写tomcat——有线程池化能力的servlet 服务的更多相关文章
- Java多线程之Executor框架和手写简易的线程池
		目录 Java多线程之一线程及其基本使用 Java多线程之二(Synchronized) Java多线程之三volatile与等待通知机制示例 线程池 什么是线程池 线程池一种线程使用模式,线程池会维 ... 
- 手写tomcat——概述
		1. 使用java 编写一个echo http服务器 使用java 编写一个echo http服务器 https://github.com/ZhongJinHacker/diy-tomcat/tree ... 
- 每天都在用,但你知道 Tomcat 的线程池有多努力吗?
		这是why的第 45 篇原创文章.说点不一样的线程池执行策略和线程拒绝策略,探讨怎么让线程池先用完最大线程池再把任务放到队列中. 荒腔走板 大家好,我是 why,一个四川程序猿,成都好男人. 先是本号 ... 
- 手写Tomcat
		学习JavaWeb之后,只知道如何部署项目到Tomcat中,而并不了解其内部如何运行,底层原理为何,因此写下此篇博客初步探究一下.学习之前需要知识铺垫已列出:Tomcat目录结构.HTTP协议.IO. ... 
- 关于 Tomcat 的线程池的理解
		默认配置下,Tomcat 会为每个连接器创建一个绑定的线程池(最大线程数 200).在大多数情况下你不需要改这个配置(除非增大最大线程数以满足高负载需要).但是 Tomcat 喜欢在每个工作者线程的 ... 
- 手写Tomcat服务器
		预备知识 编写服务器用到的知识点 1) Socket 编程2) HTML3) HTTP 协议4) 反射5) XML 解析6) 服务器编写 Socket编程 https://www.cnblogs.co ... 
- tomcat使用线程池配置高并发连接
		1:配置executor属性打开/conf/server.xml文件,在Connector之前配置一个线程池:[html] view plain copy<Executor name=" ... 
- 自己动手写http服务器——线程池(一)
		创建一个线程池,每有一个连接对象就将它添加到工作队列中,线程池中的线程通过竞争来取得任务并执行它(它是通过信号量实现的). //filename threadpool.h #ifndef THREAD ... 
- java 从零开始手写 RPC (05) reflect 反射实现通用调用之服务端
		通用调用 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 java 从零开始手写 RPC (03) 如何 ... 
随机推荐
- SAP FICO 常用table
			Table 描 述 "Table Type" "Application Class" "Data Class" Description &q ... 
- Pytorch Dataloader加速
			在进行多卡训练的时候,经常会出现GPU利用率上不来的情况,无法发挥硬件的最大实力. 造成这种现象最有可能的原因是,CPU生成数据的能力,已经跟不上GPU处理数据的能力. 方法一 常见的方法为修改Dat ... 
- Tomcat 安装及配置,创建动态的web工程
			Tomcat可以认为是对Servlet标准的实现,是一个具体的Servlet容器. 1) 将Tomcat的安装包解压到磁盘的任意位(非中文无空格) 2) Tomcat服务的 ... 
- spring boot 打包为war包方法
			刚刚接触spring boot,其快速开发的特性吸引我去研究一下.于是我写了个demo,用spring boot内置的tomcat运行的很好,但是我需要把它部署到外部的tomcat中,于是从网上查找资 ... 
- 基于单层决策树的AdaBoost算法原理+python实现
			这里整理一下实验课实现的基于单层决策树的弱分类器的AdaBoost算法. 由于是初学,实验课在找资料的时候看到别人的代码中有太多英文的缩写,不容易看懂,而且还要同时看代码实现的细节.算法的原理什么的, ... 
- testNG框架,使用@BeforeClass标注的代码,执行失败不抛出异常,只提示test ignore的解决方法
			郁闷了好久的一个问题,排错调试的时候是真滴麻烦... Google一圈,发现是testNG的Bug,升级testNG>=6.9.5,就能解决. 
- nexus 配置文件到本地maven本地仓库 失败
			Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on p ... 
- IDea折叠模块快捷键-*04
			如何折叠IntelliJ IDEA代码片段 IntelliJ IDEA 快捷键说明大全(转载) idea 字体_IDEA 新手实用插件分享:让你的 IDEA 逼格瞬间提升 
- Airbnb的动态kubernetes集群扩缩容
			Airbnb的动态kubernetes集群扩缩容 本文介绍了Airbnb的集群扩缩容的演化历史,以及当前是如何通过Cluster Autoscaler 实现自定义扩展器的.最重要的经验就是Airbnb ... 
- Rails_via牛客网
			题目 链接:https://ac.nowcoder.com/acm/contest/28537/D 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ... 
