jetty线程池的实现

线程池的基本概念

  • _threadsStarted:启动的线程数
  • _threadsIdle:空闲的线程数
  • _lastShrink:记录上次线程结束时间,用于销毁空闲线程
  • _threads:使用ConcurrentLinkedQueue来存放线程
  • _joinLock:等待线程池结束的锁【不常用】
  • _jobs:默认使用BlockingArrayQueue<Runnable>来存放任务队列,当_maxQueued>0的时候会使用ArrayBlockingQueue<Runnable>(_maxQueued)
  • _name:线程池的名字
  • _maxIdleTimeMs:线程空闲的最大时间
  • _maxThreads:最大线程数
  • _minThreads:最小线程数
  • _maxQueued:任务队列的最大长度,默认-1(无限制即Integer.MAX_VALUE)
  • _priority:默认Thread.NORM_PRIORITY,仅在测试环境中使用setThreadsPriority(int priority)【不常用】
  •  _daemon:是否daemon线程【不常用】
  • _maxStopTime:等待线程池结束的最大时间【不常用】
  • _detailedDump:是否在调用void dump(Appendable out, String indent)是输出更详细的信息


线程池的常用场景

1)实例化

     根据$JETTY_HOME/etc/jetty.xml 比如     

     <Set name="ThreadPool">
      <!-- Default queued blocking threadpool -->
      <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
        <Set name="minThreads">1</Set>
        <Set name="maxThreads">3</Set>
        <Set name="detailedDump">false</Set>
      </New>
    </Set>


会分别调用    

  • setMinThreads(int minThreads)
    • 如果已启动的线程小于最小线程数而且线程池已启动,则开启线程startThread(int threads)
  • setMaxThreads(int maxThreads)
  • setDetailedDump(boolean detailedDump)

此时

     线程组_threads为空

     任务队列_jobs为null


2)启动doStart()
  • _threadsStarted设置为0
  • 实例化_jobs为BlockingArrayQueue(默认无限制即Integer.MAX_VALUE)
  • 启动minThreads个worker线程

3)提交dispatch(Runnable job)

  • 往jobs队列中添加job
  • 如果添加成功,检查如果没有空闲线程,或者jobs中等待处理的job个数大于空闲线程  而且此时未达到最大线程数则启动新线程

4)还有几个不太常用的场景就不赘述了

  •  String dumpThread(long id) //dump单个线程信息
  •  boolean interruptThread(long id)//中断线程池中某个线程
  •  void dump(Appendable out, String indent)//dump所有线程
  • void join() //等待线程池停止
  • void doStop()//停止
线程池中的线程生命周期


1)进入job循环,不断从jobs队列取job
2)如果取不到job退出job循环进入idle循环有一个_threadsIdle变量专门记录worker线程进入idle循环个数
3)如果_maxIdleTimeMs<0(默认60秒),线程阻塞等待jobs中job,一旦取到再次进入job循环,到1)
4)否则检查当前启动线程数是否大于最小线程数,如果是且空闲时间超过_maxIdleTimeMs,则结束该线程

5)否则线程阻塞等待jobs,超时设为_maxIdleTimeMs,如果拿到job再次进入job循环到1),否则到3)


小结

  • jetty默认线程池QueuedThreadPool实现较为简单
  • 没有什么额外的管理线程来增减线程,线程的增减在运行是自动完成,比如dispatch会添加线程,线程会根据情况自己销毁
  • 和外界的常用接口就是dispatch和execute(会调用dispatch)
    • 也就是往jobs队列中丢任务
    • 某些线程池比如tomcat5或者varnish会将task直接扔给线程而不是队列,如果无空闲线程才会扔到等待队列
    • varnish中的线程被唤醒后会优先从等待队列中取任务
    • jetty 线程没有所谓的tomcat中的等待队列的概念



注意:

  • 如果_maxQueued没有设定即为-1,那么任务队列会为Integer.MAX_VALUE,此时是存在风险的
  • _maxIdleTimeMs并不完全是某个线程的空闲时间,很有可能某个线程还没空闲_maxIdleTimeMs就结束掉了,因为jetty的线程池会有一个全局的_lastShrink记录销毁时间,判断是否结束的公式是now-_lastShrink>_maxIdleTimeMs,显然更精确的公式应该是now-$(线程进入idle loop的时间)>_maxIdleTimeMs










  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Netty和Jetty都是Java中常用的网络通信库,它们的实现原理如下: 1. Netty Netty是一个基于事件驱动的异步网络通信库,它采用NIO(非阻塞IO)模型实现高性能的网络通信。Netty的主要特点包括: - 基于NIO模型,实现高性能的网络通信; - 采用事件驱动的方式,支持异步IO操作; - 提供了丰富的编解码器和处理器,方便用户进行网络通信协议的实现; - 支持多种网络协议,如TCP、UDP、HTTP、WebSocket等。 Netty的实现原理主要包括以下几个方面: - Reactor模式:Netty采用Reactor模式作为底层通信框架,通过Selector轮询IO事件,然后分发给对应的Handler进行处理; - Channel和EventLoop:Netty中的Channel表示一个网络连接,EventLoop表示一个事件循环,一个EventLoop可以对应多个Channel,通过事件驱动的方式进行异步IO操作; - Pipeline机制:Netty中的Pipeline是一种处理器链,每个Channel都有一个对应的Pipeline,通过添加不同的处理器,可以实现对网络通信数据的编解码、处理等操作; - ByteBuf:Netty中的ByteBuf是一种高效的字节缓冲区,支持读写操作,可以减少内存拷贝和提高IO效率。 2. Jetty Jetty是一个基于Servlet容器的Web服务器和Servlet容器,它采用线程池和NIO模型实现高性能的Web服务。Jetty的主要特点包括: - 基于Servlet容器,支持常用的Web应用开发技术; - 支持异步Servlet和WebSocket等技术,提高Web应用的性能和交互效果; - 支持HTTP/2和WebSocket协议,提升Web应用的传输效率; - 支持多种Web容器集群部署方式,提高Web应用的可伸缩性。 Jetty实现原理主要包括以下几个方面: - Servlet容器:Jetty采用Servlet容器作为底层通信框架,通过处理HTTP请求和响应来实现Web服务; - 线程池和NIO模型:Jetty采用线程池和NIO模型实现高性能的Web服务,通过异步IO操作来提高Web应用的吞吐量; - WebSocket和HTTP/2支持:Jetty支持WebSocket和HTTP/2协议,提高Web应用的传输效率和交互效果; - Web容器集群:Jetty支持多种Web容器集群部署方式,提高Web应用的可伸缩性。 总的来说,Netty和Jetty都是高性能的网络通信库,它们实现原理的核心都是采用了NIO模型和事件驱动的方式来实现异步IO操作。Netty主要用于实现网络通信协议,如TCP、UDP、HTTP、WebSocket等,而Jetty主要用于实现Web服务器和Servlet容器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值