【仿写tomcat】六、解析xml文件配置端口、线程池核心参数

news2025/1/24 0:53:56

线程池改造

上一篇文章中我们用了Excutors创建了线程,这里我们将它改造成包含所有线程池核心参数的形式。

package com.tomcatServer.http;


import java.util.concurrent.*;

/**
 * 线程池跑龙套
 *
 * @author ez4sterben
 * @date 2023/08/05
 */
public class ThreadPool {
    private int corePoolSize;
    private int maximumPoolSize;
    private long keepAliveTime;

    private static ThreadPoolExecutor threadPoolExecutor;

    public ThreadPool() {

    }

    public synchronized ThreadPoolExecutor getInstance() {
        if (threadPoolExecutor == null) {
            BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
            ThreadFactory threadFactory = Executors.defaultThreadFactory();
            threadPoolExecutor = new ThreadPoolExecutor(
                    corePoolSize,
                    maximumPoolSize,
                    keepAliveTime,
                    TimeUnit.SECONDS,
                    workQueue,
                    threadFactory
            );
        }
        return threadPoolExecutor;
    }

    public static synchronized void shutdown() {
        if (threadPoolExecutor != null) {
            threadPoolExecutor.shutdown();
            threadPoolExecutor = null;
        }
    }

    public int getCorePoolSize() {
        return corePoolSize;
    }

    public void setCorePoolSize(int corePoolSize) {
        this.corePoolSize = corePoolSize;
    }

    public void setMaximumPoolSize(int maximumPoolSize) {
        this.maximumPoolSize = maximumPoolSize;
    }

    public void setKeepAliveTime(long keepAliveTime) {
        this.keepAliveTime = keepAliveTime;
    }
}

主方法中对多线程操作部分改为使用CompletableFuture执行

 // 5.初始化线程池
        ThreadPoolExecutor executor = XmlParseUtil.initThreadPool(ROOT);
// 6.处理http请求
        try {
            SocketStore.connect(port);
            while (true){
                Socket accept = SocketStore.getSocket().accept();
                if (accept != null){
                    CompletableFuture.runAsync(() -> {
                        try {
                            SocketStore.handleRequest(accept);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }, executor);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            SocketStore.close();
        }

解析xml文件

现在我们有一个server.xml文件,我想解析其中的端口号以及线程池参数

<tomcat-server>
    <port>80</port>
    <core-pool-size>4</core-pool-size>
    <maximum-pool-size>8</maximum-pool-size>
    <keep-alive-time>60</keep-alive-time>
</tomcat-server>

如果想完成这个功能可以直接使用java本身自带的工具类,下面附上代码

package com.tomcatServer.utils;

import com.tomcatServer.http.ThreadPool;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ThreadPoolExecutor;

public class XmlParseUtil {
    public static Integer parseServerConfig(String root){
        int port = 8080;
        try {
            NodeList nodeList = getServerConfig(root);
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) node;
                    port = Integer.parseInt(element.getElementsByTagName("port").item(0).getTextContent().trim());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return port;
    }

    public static ThreadPoolExecutor initThreadPool(String root){
        ThreadPool threadPool = new ThreadPool();
        int corePoolSize = 4;
        int maximumPoolSize = 8;
        int keepAliveTime = 60;
        try {
            NodeList nodeList = getServerConfig(root);
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) node;
                    corePoolSize = Integer.parseInt(element.getElementsByTagName("core-pool-size").item(0).getTextContent().trim());
                    maximumPoolSize = Integer.parseInt(element.getElementsByTagName("maximum-pool-size").item(0).getTextContent().trim());
                    keepAliveTime = Integer.parseInt(element.getElementsByTagName("keep-alive-time").item(0).getTextContent().trim());

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        threadPool.setCorePoolSize(corePoolSize);
        threadPool.setMaximumPoolSize(maximumPoolSize);
        threadPool.setKeepAliveTime(keepAliveTime);

        System.out.println(threadPool.getCorePoolSize());
        return threadPool.getInstance();
    }

    private static NodeList getServerConfig(String root) throws ParserConfigurationException, SAXException, IOException {
        File inputFile = new File(root + "\\src\\main\\java\\com\\tomcatServer\\config\\server.xml");

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(inputFile);
        document.getDocumentElement().normalize();
        return document.getElementsByTagName("tomcat-server");
    }
}

启动测试

在这里插入图片描述
现在我的配置文件是这样的,在主方法中打印一下端口号,如果是80说明这个xml扫描成功了,然后我们再去访问80端口的Index页面。
在这里插入图片描述
在这里插入图片描述
http://localhost:8080/index.html
尝试访问8080时,已经无法访问了
在这里插入图片描述
接下来访问80端口
在这里插入图片描述
访问成功

现在我们的tomcat已经有一定的功能了,下一篇作者将对整个tomcat的代码结构做一些优化,并将现阶段的代码分享给读者。

【仿写tomcat】七、项目结构优化以及代码开源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/894860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

社科院与美国杜兰大学金融管理硕士项目——畅游于金融世界

随着社会经济的不断发展&#xff0c;职场竞争愈发激烈&#xff0c;很多同学都打算通过报考研究生来实现深造&#xff0c;提升自己的综合能力和竞争优势&#xff0c;获得优质的证书。而对于金融专业的学生和在职人员来说&#xff0c;社科院与美国杜兰大学金融管理硕士项目是一个…

ElasticSearch7.x + kibana7.x使用记录

目录 查询所有索引 查询索引的mapping信息 添加索引的同时添加mapping 在原有基础上新增字段 旧的索引迁移到新的索引&#xff08;使用场景&#xff1a;数据迁移、索引优化、数据转换&#xff09; 查询索引下的文档总数 场景1&#xff1a;某一个字段的值是数组&#xff0…

数据的深海潜行:数据湖、数据仓库与数据湖库之间的微妙关系

导言&#xff1a;数据的重要性与存储挑战 在这个信息爆炸的时代&#xff0c;数据已经成为企业的核心资产&#xff0c;而如何高效、安全、便捷地存储这些数据&#xff0c;更是每个组织面临的重大挑战。 数据作为组织的核心资产 数据在过去的几十年里从一个辅助工具演变成企业的…

视频怎么转换成gif表情包?三步完成视频在线转gif

小伙伴们在使用gif表情包的时候&#xff0c;都会注意到有些是视频片段&#xff0c;其实视频转换成gif动图已经很常见了&#xff0c;今天就来给大家演示一下使用视频转gif工具&#xff08;https://www.gif.cn&#xff09;来将视频在线转gif&#xff0c;一起来学习一下吧。 打开…

ps由于找不到msvcp140.dll无法继续执行需要怎么处理

最近在使用Photoshop时遇到了一个问题&#xff0c;它提示我缺少了msvcp140.dll文件。这让我无法正常使用Photoshop&#xff0c;非常困扰。然而&#xff0c;通过一番尝试和研究&#xff0c;我终于成功修复了这个问题&#xff0c;小编就把修复方法分享给大家。 ps为什么会由于找不…

【文生图系列】Denoising Diffusion Probabilistic Models论文解读

文章目录 扩散模型扩散过程反向过程优化目标 训练过程参考 此篇论文是DDPM的奠基之作&#xff0c;后续扩散模型相关论文都基本继承了前向加噪-反向降噪-训练这样的框架。论文全是公式&#xff0c;理解起来好难好难。 【文生图系列】基础篇-马尔可夫链 【文生图系列】基础篇-变分…

springboot中的properties配置文件:MySQL密码添加双引号会报错

在springboot项目中&#xff0c;如果使用的配置文件是properties 格式&#xff0c;那么给属性的值添加双引号可能会出错&#xff0c;比如给MySQL的密码添加双引号&#xff1a; 我们在调试模式下&#xff0c;一探究竟&#xff1a; 然后在其poolProperties中查看&#xff0c;密…

如何快速在vscode中实现不同python文件的对比查看

总体而言&#xff1a;两种方式。一种是直接点击vscode右上角的图标&#xff08;见下图&#xff09;。 另一种方式就是使用快捷键啦“**Ctrl**”&#xff0c;用的时候选中想要对比的python文件&#xff0c;然后快捷键就可以达到下图效果了&#xff1a; 建议大家直接使用第二种…

Java课题笔记~ SpringBoot基础配置

二、基础配置 1. 配置文件格式 问题导入 框架常见的配置文件有哪几种形式&#xff1f; 1.1 修改服务器端口 http://localhost:8080/books/1 >>> http://localhost/books/1 SpringBoot提供了多种属性配置方式 application.properties server.port80 applicati…

电动汽车太秀了!用一个技巧搞定了蓄电池!

当涉及能源存储和供应&#xff0c;特别是在太阳能、电动车和不间断电源等领域&#xff0c;蓄电池无疑是关键的组成部分。然而&#xff0c;蓄电池的状态、性能和健康状况对于系统的可靠性和效率至关重要。 蓄电池监控通过实时监测、数据分析和预警功能&#xff0c;它提供了更高效…

PCB老化测试注意事项和操作流程

PCB老化测试是为了评估PCB在实际应用环境中的可靠性和寿命而进行的测试。以下是PCB老化测试的一般步骤和一些注意事项&#xff1a; 步骤&#xff1a; 1. 确定老化条件&#xff1a;根据实际应用环境和需求&#xff0c;确定老化测试的条件&#xff0c;如温度、湿度、电压等。这些…

基于Redis实现关注、取关、共同关注及消息推送(含源码)

微信公众号访问地址&#xff1a;基于Redis实现关注、取关、共同关注及消息推送(含源码) 推荐文章&#xff1a; 1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表; 2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据; 3、为什么引入Rediss…

【3Ds Max】可编辑多边形“点”层级的简单使用

目录 简介 示例 &#xff08;1&#xff09;移除 &#xff08;2&#xff09;断开 &#xff08;3&#xff09;焊接 &#xff08;4&#xff09;挤出 &#xff08;5&#xff09;切角 &#xff08;6&#xff09;目标焊接 &#xff08;7&#xff09;连接 简介 在3ds Max中&…

Golang使用MinIO

最近在使用Golang做了一个网盘项目&#xff08;学习&#xff09;&#xff0c;文件存储一直保存在本地&#xff08;各厂商提供的oss贵&#xff09;&#xff0c;所以就在思考怎么来处理这些文件&#xff0c;类似的方案很对hdfs、fastdfs&#xff0c;但这其中MinIO是最近几年比较火…

网安周报|Monti Ransomware团伙推出了一个新的Linux加密器

Monti Ransomware团伙推出了一个新的Linux加密器 经过两个月的休息&#xff0c;Monti 勒索软件运营商带着新的 Linux 版本的加密器返回。该变体被用于针对政府和法律部门组织的攻击。研究人员注意到两个团伙的TTP之间有多个相似之处&#xff0c;Monti运营商还基于Conti泄露的源…

Synchronized与Java线程的关系

前言 ​ Java多线程处理任务时&#xff0c;为了线程安全&#xff0c;通常会对共享资源进行加锁&#xff0c;拿到锁的线程才能进行访问共享资源。而加锁方式通过都是Synchronized锁或者Lock锁。 ​ 那么多线程在协同工作的时候&#xff0c;线程状态的变化都与锁对象有关系。 …

安防监控视频云存储平台EasyNVR出现内核报错的情况该如何解决?

安防视频监控汇聚EasyNVR视频集中存储平台&#xff0c;是基于RTSP/Onvif协议的安防视频平台&#xff0c;可支持将接入的视频流进行全平台、全终端分发&#xff0c;分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等格式。 近期有用户联系到我们&#xff0c;EasyNVR…

lab3 pgtbl

Pre 在这个lab中&#xff0c;你将探索页表&#xff0c;并且修改它们以简化从用户空间拷贝数据到内核空间的函数 在开始之前&#xff0c;需要完成 阅读xv6 book的第3章kern/memlayout.h 有关内存的布局kern/vm.c 包含大部分虚拟内存的代码kernel/kalloc.c 分配和释放虚拟内存的代…

Redisson实现分布式锁示例

一、引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.0</version></dependency>二、配置类 import org.redisson.Redisson; import org.redisson.api.RedissonClient;…

无涯教程-Perl - wantarray函数

描述 如果当前正在执行的函数的context正在寻找列表值,则此函数返回true。在标量context中返回false。 语法 以下是此函数的简单语法- wantarray返回值 如果没有context,则此函数返回undef&#xff1b;如果lvalue需要标量,则该函数返回0。 例 以下是显示其基本用法的示例…