• C.
    2023-12-19 来自江苏
    Tomcat 为什么用一个简单的 queue 来实现多线程而不是用 JDK 自带的线程池? 1.自定义可以更好地控制,还有后期的优化 2.历史原因,可能当时内置线程池功能没那么完善 现在,应该也支持使用JDK自带的线程池 交个作业:https://github.com/caozhenyuan/mini-tomcat

    作者回复: 你的理解原则上是正确的。具体一点,jdk线程池标准模式当核心线程数超过后直接进队列,不是新建线程,这个方式不适合io型多任务。

    
    
  • so long
    2023-12-18 来自浙江
    jdk线程池,在并发数超过核心线程数后,会先将请求任务添加到队列中,而不是创建新的线程处理请求任务,所以会存在一定的延迟

    作者回复: 是的。jdk线程池用的普通队列,不适合io型多任务处理。

    
    
  • peter
    2023-12-18 来自北京
    请教老师几个问题: Q1:用notifyAll唤醒所有线程,不对吧。 假如有5个线程,connector同时启动这5个线程,5个线程处于wait状态。假设此时来了一个连接请求,由其中的一个线程A处理,那么,connector应该只唤醒这线程A吧。用notifyall会唤醒全部5个线程,难道5个线程处理同一个请求吗? Q2:recycle方法有多线程问题吗? 假设有5个线程在处理5个请求,这5个线程都会调用recycle方法,此时会存在并发问题吗? Q3:线程池的大小一般为多大? 有经验公式吗?

    作者回复: 都是好问题。notifyall会唤醒全部,但是代码中一旦标志不符合就会继续等待,不会出现几个同时处理,你仔细跟代码。recycle我也认为会出现并发问题,你这个观察很好,这段代码取自Tomcat4源代码,应该是有问题。 线程池大小,很复杂,大师们有个公式,依赖于核还有计算时间等待时间,但是实际系统复杂,很不好估算计算时间等待时间,并且还有别的进程共用CPU,所以呢,不好回答,我一般拍脑袋就是讲线程池大小设置为核的数量。

    共 3 条评论
    
  • HH🐷🐠
    2023-12-18 来自广东
    🌝🌝自带JDK线程池初始化指定线程数, 共用这些线程, 可能这次在A线程执行, 下次在B线程执行,上下文切来切去造成性能不必要的开销,在网络中这点开销算是很大了。 只能想到这个点,不知道是否正确

    作者回复: 简单来讲,jdk线程池使用普通队列,当并发任务数超过了核心大小后,直接进队列等待,这种方式比较适合CPU型多任务。但是servlet的应用场景是io型的,所以Tomcat要自己实现。我们也可以比较简单地重写jdk队列的offer方法,数量没有达到最大线程数就返回false,让线程池新建线程。

    
    