点击查看代码
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. SAP FICO 常用table

    Table 描 述 "Table Type" "Application Class" "Data Class" Description &q ...

  2. Pytorch Dataloader加速

    在进行多卡训练的时候,经常会出现GPU利用率上不来的情况,无法发挥硬件的最大实力. 造成这种现象最有可能的原因是,CPU生成数据的能力,已经跟不上GPU处理数据的能力. 方法一 常见的方法为修改Dat ...

  3. Tomcat 安装及配置,创建动态的web工程

    Tomcat可以认为是对Servlet标准的实现,是一个具体的Servlet容器. 1)        将Tomcat的安装包解压到磁盘的任意位(非中文无空格) 2)        Tomcat服务的 ...

  4. spring boot 打包为war包方法

    刚刚接触spring boot,其快速开发的特性吸引我去研究一下.于是我写了个demo,用spring boot内置的tomcat运行的很好,但是我需要把它部署到外部的tomcat中,于是从网上查找资 ...

  5. 基于单层决策树的AdaBoost算法原理+python实现

    这里整理一下实验课实现的基于单层决策树的弱分类器的AdaBoost算法. 由于是初学,实验课在找资料的时候看到别人的代码中有太多英文的缩写,不容易看懂,而且还要同时看代码实现的细节.算法的原理什么的, ...

  6. testNG框架,使用@BeforeClass标注的代码,执行失败不抛出异常,只提示test ignore的解决方法

    郁闷了好久的一个问题,排错调试的时候是真滴麻烦... Google一圈,发现是testNG的Bug,升级testNG>=6.9.5,就能解决.

  7. nexus 配置文件到本地maven本地仓库 失败

    Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on p ...

  8. IDea折叠模块快捷键-*04

    如何折叠IntelliJ IDEA代码片段 IntelliJ IDEA 快捷键说明大全(转载) idea 字体_IDEA 新手实用插件分享:让你的 IDEA 逼格瞬间提升

  9. Airbnb的动态kubernetes集群扩缩容

    Airbnb的动态kubernetes集群扩缩容 本文介绍了Airbnb的集群扩缩容的演化历史,以及当前是如何通过Cluster Autoscaler 实现自定义扩展器的.最重要的经验就是Airbnb ...

  10. Rails_via牛客网

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