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

线程池改造

上一篇文章中我们用了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>80port>
    <core-pool-size>4core-pool-size>
    <maximum-pool-size>8maximum-pool-size>
    <keep-alive-time>60keep-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");
    }
}

启动测试

【仿写tomcat】六、解析xml文件配置端口、线程池核心参数_第1张图片
现在我的配置文件是这样的,在主方法中打印一下端口号,如果是80说明这个xml扫描成功了,然后我们再去访问80端口的Index页面。
【仿写tomcat】六、解析xml文件配置端口、线程池核心参数_第2张图片
【仿写tomcat】六、解析xml文件配置端口、线程池核心参数_第3张图片
http://localhost:8080/index.html
尝试访问8080时,已经无法访问了
【仿写tomcat】六、解析xml文件配置端口、线程池核心参数_第4张图片
接下来访问80端口
【仿写tomcat】六、解析xml文件配置端口、线程池核心参数_第5张图片
访问成功

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

你可能感兴趣的:(源码仿写,tomcat,xml,java)