手写一个Tomcat实现请求的异步处理!

首先梳理一下大致流程

客户端发送请求  ->  tomcat分配一个线程处理请求  -> 找到对应的注册的Servlet执行 -> 获得输出流返回。

核心线程池,通过ThreadPoolExecutor创建一个线程池,选择阻塞的有界队列 ArrayBlokingQueue,防止资源耗尽。通过创建ServerSocket,监听再拿到一个Socket,交给异步的CompletableFuture 进行处理。

private void runServer() {
        ServerSocket serverSocket = null;
        ThreadPoolExecutor requestPool = null;
        ArrayBlockingQueue<Runnable> runnableQueue = new ArrayBlockingQueue<>(150);
        try {
            serverSocket = new ServerSocket(PORT, 100);
            requestPool = new ThreadPoolExecutor(
                    100
                    , 600
                    , 3000
                    , TimeUnit.MILLISECONDS
                    , runnableQueue
                    , CitrusThreadFactory.getFactoryOne()
                    , new ThreadPoolExecutor.AbortPolicy()
            );

            printSystemInfo();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (serverSocket != null) {
            while (!serverSocket.isClosed()) {
                Socket socket = null;
                try {
                    socket = serverSocket.accept();
                    CompletableFuture.runAsync(new ServerService(socket), requestPool);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

自定义一个ThreadFactory,用于自定义线程的名称,方便查看。 

 private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    CitrusThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                Thread.currentThread().getThreadGroup();
        namePrefix = "Servlet核心请求线程池: " +
                POOL_NUMBER.getAndIncrement() +
                " :请求线程 :";
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                namePrefix + threadNumber.getAndIncrement(),
                0);
        if (t.isDaemon()) {
            t.setDaemon(false);
        }
        if (t.getPriority() != Thread.NORM_PRIORITY) {
            t.setPriority(Thread.NORM_PRIORITY);
        }
        return t;
    }

    public static ThreadFactory  getFactoryOne(){
        return new CitrusThreadFactory();
    }

…… 

在serverService再对请求进行处理,通过拿到 输入输出流,解析http协议内容,再通过指定输入流返回指定协议格式的数据即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值