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

【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队列里有任务,就拿出来提交到线程池去执行
// 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值