点击查看代码
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

手写tomcat——有线程池化能力的servlet 服务的更多相关文章

  1. Java多线程之Executor框架和手写简易的线程池

    目录 Java多线程之一线程及其基本使用 Java多线程之二(Synchronized) Java多线程之三volatile与等待通知机制示例 线程池 什么是线程池 线程池一种线程使用模式,线程池会维 ...

  2. 手写tomcat——概述

    1. 使用java 编写一个echo http服务器 使用java 编写一个echo http服务器 https://github.com/ZhongJinHacker/diy-tomcat/tree ...

  3. 每天都在用,但你知道 Tomcat 的线程池有多努力吗?

    这是why的第 45 篇原创文章.说点不一样的线程池执行策略和线程拒绝策略,探讨怎么让线程池先用完最大线程池再把任务放到队列中. 荒腔走板 大家好,我是 why,一个四川程序猿,成都好男人. 先是本号 ...

  4. 手写Tomcat

    学习JavaWeb之后,只知道如何部署项目到Tomcat中,而并不了解其内部如何运行,底层原理为何,因此写下此篇博客初步探究一下.学习之前需要知识铺垫已列出:Tomcat目录结构.HTTP协议.IO. ...

  5. 关于 Tomcat 的线程池的理解

    默认配置下,Tomcat 会为每个连接器创建一个绑定的线程池(最大线程数 200).在大多数情况下你不需要改这个配置(除非增大最大线程数以满足高负载需要).但是 Tomcat 喜欢在每个工作者线程的 ...

  6. 手写Tomcat服务器

    预备知识 编写服务器用到的知识点 1) Socket 编程2) HTML3) HTTP 协议4) 反射5) XML 解析6) 服务器编写 Socket编程 https://www.cnblogs.co ...

  7. tomcat使用线程池配置高并发连接

    1:配置executor属性打开/conf/server.xml文件,在Connector之前配置一个线程池:[html] view plain copy<Executor name=" ...

  8. 自己动手写http服务器——线程池(一)

    创建一个线程池,每有一个连接对象就将它添加到工作队列中,线程池中的线程通过竞争来取得任务并执行它(它是通过信号量实现的). //filename threadpool.h #ifndef THREAD ...

  9. java 从零开始手写 RPC (05) reflect 反射实现通用调用之服务端

    通用调用 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 java 从零开始手写 RPC (03) 如何 ...

随机推荐

  1. UiPath录制器的介绍和使用

    一.录制器(Recording)的介绍 录制器是UiPath Studio的重要组成部分,可以帮助您在自动化业务流程时节省大量时间.此功能使您可以轻松地在屏幕上捕获用户的动作并将其转换为序列. 二.录 ...

  2. Sentiment analysis in nlp

    Sentiment analysis in nlp The goal of the program is to analysis the article title is Sarcasm or not ...

  3. bat-设置oracle服务

    1.停止oracle所有服务 并将服务设置为手动启动 @echo off echo oracle服务--------停止 net stop OracleVssWriterORCL net stop O ...

  4. Python递归函数的定义和几个小例子

    递归函数 (1)什么是递归函数? 我们都知道,一个函数可以调用其他函数.如果这个函数在内部调用它自己,那么这个函数就叫递归函数. (2)递归函数的作用 举个例子,我们来计算阶乘 n! = 1 * 2 ...

  5. 市面上的工业ERP系统如何区别?存在什么样的不同?

    工业发展当中所要涉及到的管理是繁琐而复杂的,在ERP系统的拓展开发中,市面上出现了很多的工业ERP系统来让企业选择.这是近年来非常受欢迎的一种管理手段,依靠计算机系统的强大功能,来实现数据化的管理,企 ...

  6. github碰到的问题

    下载问题 自己编译一下 mvn clear mvn compile mvn package 自己编译之后的文件,然后解压即可,第一次自己傻傻的,直接用源码跑,少报错! 项目预览问题 添加1s即可 下载 ...

  7. [USACO 2009 Mar S]Look Up_via牛客网

    题目 链接:https://ac.nowcoder.com/acm/contest/28537/N 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ...

  8. Unity3D学习笔记10——纹理数组

    目录 1. 概述 2. 详论 2.1. 实现 2.2. 注意 3. 参考 1. 概述 个人认为,纹理数组是一个非常有用的图形特性.纹理本质上是一个二维的图形数据:通过纹理数组,给图形数据再加上了一个维 ...

  9. 使用Python3.7配合协同过滤算法(base on user,基于人)构建一套简单的精准推荐系统(个性化推荐)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_136 时至2020年,个性化推荐可谓风生水起,Youtube,Netflix,甚至于Pornhub,这些在互联网上叱咤风云的流媒体 ...

  10. Vue el与data的两种写法 && Object.defineProperty方法

    1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8" /> 5 & ...