【resin】 resin3 线程池与IO模型(1)

本文深入解析Resin3的线程池架构,包括Port、TcpConnection与ThreadPool三个核心组件的工作原理,揭示其线程复用机制及任务调度流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【resin】 resin3 线程池与IO模型(1)

本文所讨论的线程池及IO是基于resin3.1.13开源版

resin3的线程池IO相关的类主要是3个:
Port、TcpConnection、ThreadPool

TcpConnection:处理tcp链接的task
Port:创建TcpConnection task的主线程
TreadPool:resin线程池,里面还包含了3个核心类
     Item:work 线程,处理提交的task
     ThreadLauncher:Daemon线程,负责创建work线程
     ScheduleThread:Daemon工作线程,不断轮询task队列,有task就提交到线程池处理

下面贴出源码:为说明核心逻辑,只展示核心的代码
本文所分析为个人理解,欢迎指出不足之处或分享你的观点

 
在Port类中,创建的tcpconnection task,通过ThreadPool的schedule方法提交task
 ThreadPool.getThreadPool().schedule(conn);

看看schedule方法:
schedule方法内部最终调用的是重载方法:
private boolean schedule(Runnable task,
                     ClassLoader loader,
                     int freeThreads,
                     long expireTime,
                     boolean queueIfFull)
  {
    Item poolItem = null;

    while (poolItem == null) {
      try {
      synchronized ( _idleLock) {
        if (! _isInit)
          init();
     
        int idleCount = _idleCount;
        int freeCount = idleCount + _threadMax - _threadCount;
        boolean startNew = false;

        poolItem = _idleHead;
        if (poolItem != null && freeThreads < freeCount) {
          
          _idleHead = poolItem. _next;

          poolItem. _next = null;
          poolItem. _prev = null;
          poolItem. _isIdle = false;
          if ( _idleHead != null)
            _idleHead. _prev = null;

          _idleCount--;

          if (idleCount < _threadIdleMin)
            startNew = true;
        }
        else
          startNew = true;

        /**
         * 如果当前工作线程数不够,就通知 launcher 去创建工作线程
         */
        if (startNew) {
          synchronized ( _launcher) {
            _launcher.notifyAll();
          }
         
          /**
           * 如果没有空闲的线程,就把task 添加到task队列里
           */
          if (poolItem == null) {
            if (queueIfFull) {
             synchronized ( _taskQueue) {
              _taskQueue.add(task);
              _loaderQueue.add(loader);
              _taskQueue.notifyAll();
            }            
             return false;
            }

           。。。。。。
          }
        }
      }
      } catch (OutOfMemoryError e) {
       。。。。。。
    }
    /**
     * 有空闲的线程,就执行 提交的task
     */
    poolItem.start(task, loader);   

    return true;
  }
//从上面的代码可以看出,resin3的work线程是通过链表来维持的
//在这个方法里主要关注三点:
// 1.当前work线程不过,就notify  ThreadLauncher去创建work线程
// 2.当前没有空闲的work线程,就把任务丢到task队列了 _taskQueue.add(task)
// 3.如果有work线程,就让这个线程去执行任务吧  poolItem.start(task, loader);

下面看看 ThreadLauncher 里的执行逻辑
public void run()
    {
      try {
      for (int i = 0; i < _threadIdleMin; i++)
        startConnection(0);
      } catch (Throwable e) {
      e.printStackTrace();
      }
      while (true) {
      try {
        startConnection(10000);
        Thread.currentThread(). yield();
      } catch (OutOfMemoryError e) {
      }
    }

private boolean startConnection(long waitTime)
      throws InterruptedException
    {
      boolean doStart = true;
      synchronized ( _idleLock) {
      int idleCount = _idleCount;

      if (_threadMax < _threadCount + _startCount)
        doStart = false;
      else if (_threadIdleMin < idleCount + _startCount)
        doStart = false;
      if (doStart)
        _startCount++;
      }

      if (doStart) {
      try {
        Item poolItem = new Item();    
        Thread thread = new Thread(poolItem, poolItem.getName());
        thread.setDaemon( true);
        thread.start();
      } catch (Throwable e) {
      }
      }
      else {
      Thread. interrupted();
      synchronized ( this) {
        wait(waitTime);
        return false;
      }
      }

      return true;
    }
// ThreadLauncher 里开始会先创建 _threadIdleMin 个work线程来执行任务
// 然后会根据当前的空闲work线程数和当前active线程数的条件来创建work线程

下面看看 work线程 Item
work线程里核心的逻辑为 runTasks 方法:
 private void runTasks()
    {   
      boolean isIdle = false;
      /**
       * 工作线程不停轮询,直到有task可执行会 消亡
       */
      while (true) {
      try {
        // put the thread into the idle ring
        if (! isIdle) {       
          isIdle = true;       
          synchronized ( _idleLock) {
            long now = Alarm. getCurrentTime();
            if ( _threadIdleMax < _idleCount
              && _threadIdleOverflowExpire < now) {
             _threadIdleOverflowExpire = now + OVERFLOW_TIMEOUT;
             return;
            }
           
            _next = _idleHead;
            _prev = null;
            _isIdle = true;

            if ( _idleHead != null)
             _idleHead. _prev = this;

            _idleHead = this;
            _idleCount++;
          }
        }

        Runnable task = null;
      
        // wait for the next available task
        synchronized ( this) {
          if ( _task == null) {
            wait(60000L);
          }

          task = _task;
          _task = null;
        }

        // if the task is available, run it in the proper context
        if (task != null) {             
          isIdle = false;

          try {
            task.run();
          } catch (Throwable e) {
          } finally {
          }
        }
        else {
          boolean isDead = false;
          boolean isReset = false;

          // check to see if we're over the idle thread limit
          synchronized ( _idleLock) {
            long now = Alarm. getCurrentTime();
           
            if ( _isIdle
              && (( _threadIdleMax < _idleCount
                   && _threadIdleOverflowExpire < now)
                  || _resetCount != _threadResetCount)) {
             _threadIdleOverflowExpire = now + OVERFLOW_TIMEOUT;
            
            isDead = true;
            isReset = _resetCount != _threadResetCount;
           
            Item next = _next;
            Item prev = _prev;

             _next = null;
             _prev = null;
             _isIdle = false;

             if (next != null)
              next. _prev = prev;

             if (prev != null)
              prev. _next = next;
             else
              _idleHead = next;

             _idleCount--;
            }
          }

          if (isReset) {
            synchronized ( _launcher) {
             _launcher.notifyAll();
            }
          }
        /**
         * 没有任务了,而且空闲线程太多了,就光荣退役好了
         */
          if (isDead)
            return;
        }
      } catch (Throwable e) {
      }
      }
    }
  }
// Item 线程主要逻辑:
// 1 把空闲的work线程放在 链表的头部
// 2 如果当前有任务,就执行任务 task.run();
// 3 如果当前没有任务,就判断空闲work数量是否过多,多了,就光荣退役了
//

最后在看看定时工作线程 ScheduleThread

public void run()
    {     
      while (true) {
      try {
        Runnable task = null;
        ClassLoader loader = null;

        Thread. interrupted();
       
        synchronized ( _taskQueue) {
          if ( _taskQueue.size() > 0) {
            task = _taskQueue.remove(0);
            loader = _loaderQueue.remove(0);
          }
          else {
            try {
             _taskQueue.wait(60000);
            } catch (Throwable e) {
            }
          }
        }

        if (task != null) {
          schedule(task, loader, _threadIdleMin, MAX_EXPIRE, false);
        }
      } catch (OutOfMemoryError e) {
        System. exit(10);
      } catch (Throwable e) {
      }
      }
    }
  }
// 定时工作线程的目的很明确,就是不断轮询,只要task队列里有任务,就拿出来提交到线程池去执行
// 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值