当前位置: 首页 > news >正文

Mina2.0框架源码剖析(二)

 上一篇介绍了几个核心的接口,这一篇主要介绍实现这些接口的抽象基类。首先是实现IoService接口的AbstractIoService类。它包含了一个Executor来处理到来的事件。每个AbstractIoService都一个AtomicInteger类型的id号,确保每个id的唯一性。

它内部的Executor可以选择是从外部传递进构造函数中,也可以在实例内部自行构造,若是后者,则它将是ThreadPoolExecutor类的一个实例,即是Executor线程池中的一员。代码如下:

复制代码
     if (executor == null) 
        {
            this.executor = Executors.newCachedThreadPool();
            createdExecutor = true;
        } 
        else 
        {
            this.executor = executor;
            createdExecutor = false;
        }
复制代码
      其中有一个IdleStatusChecker成员,它用来对服务的空闲状态进行检查,在一个服务激活时会将服务纳入到检查名单中,而在服务失效时会将服务从名单中剔除。会单独开一个线程进行具体的空闲检查,这是通过下面这个线程类来负责的:

复制代码
private class NotifyingTaskImpl implements NotifyingTask 
{
        private volatile boolean cancelled;//取消检查标志
        private volatile Thread thread;
        public void run()
{
            thread = Thread.currentThread();
            try {
                while (!cancelled) 
{
                    //每隔1秒检查一次空闲状态
                    long currentTime = System.currentTimeMillis();
                    notifyServices(currentTime);
                    notifySessions(currentTime);
                    try 
{
                        Thread.sleep(1000);
                    } catch (InterruptedException e) 
{
                        // will exit the loop if interrupted from interrupt()
                    }
                }
            }
 Finally
 {
                thread = null;
            }
        }
}
复制代码
具体的空闲检查代码如下,超过能容忍的最大空闲时间,就会fire出SessionIdle事件,上文也说过空闲有三种类型:读端空,写端空,双端空。

复制代码
notifyIdleSession1(s, currentTime,
                s.getConfig().getIdleTimeInMillis(IdleStatus.BOTH_IDLE),IdleStatus.BOTH_IDLE,Math.max(s.getLastIoTime(),s.getLastIdleTime(IdleStatus.BOTH_IDLE)));
    private static void notifyIdleSession1(
            AbstractIoSession session, long currentTime,
            long idleTime, IdleStatus status, long lastIoTime) 
{
        if (idleTime > 0 && lastIoTime != 0
                && currentTime - lastIoTime >= idleTime) 
{
            session.getFilterChain().fireSessionIdle(status);
        }
}
复制代码
     在释放资源的方法时,首先去获取释放锁disposalLock才行,然后具体的释放动作是通过dispose0完成的,接着取消掉空闲检查线程,此外,若线程是内部创建的线程池中的一员,则通过线程池去关闭线程。

 复制代码
   public final void dispose() 
{
        IoFuture disposalFuture;
        synchronized (disposalLock) 
{//获取释放锁
            disposalFuture = this.disposalFuture;
            if (!disposing) {
                disposing = true;
                try {
                    this.disposalFuture = disposalFuture = dispose0();//具体释放动作
                } catch (Exception e) {
                    ExceptionMonitor.getInstance().exceptionCaught(e);
                } finally {
                    if (disposalFuture == null) {
                        disposed = true;
                    }
                }
            }
        }
        idleStatusChecker.getNotifyingTask().cancel();
        if (disposalFuture != null)
{//无中断地等待释放动作完成
            disposalFuture.awaitUninterruptibly();
        }
        if (createdExecutor) 
{通过线程池去关闭线程
            ExecutorService e = (ExecutorService) executor;
            e.shutdown();
            while (!e.isTerminated()) {
                try {
                    e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
                } catch (InterruptedException e1) {
                    // Ignore; it should end shortly.
                }
            }
        }
        disposed = true;
    }
复制代码
     再来看会话初始化完成后的动作每个session都保持有自己的属性映射图,在会话结束初始化时,应该设置这个AttributeMap。

((AbstractIoSession) session).setAttributeMap(session.getService()
                    .getSessionDataStructureFactory().getAttributeMap(session));
     除此以为,还应该为会话配置写请求队列:

((AbstractIoSession) session).setWriteRequestQueue(session
                    .getService().getSessionDataStructureFactory()
                    .getWriteRequestQueue(session));
     在初始化时会在会话的属性中加入一项SESSION_CREATED_FUTURE,这个属性会在连接真正建立后从会话中去除。

        if (future != null && future instanceof ConnectFuture) 
{
           session.setAttribute(DefaultIoFilterChain.SESSION_CREATED_FUTURE,
                    future);
 }



本文转自Phinecos(洞庭散人)博客园博客,原文链接http://www.cnblogs.com/phinecos/archive/2008/12/04/1347394.html,如需转载请自行联系原作者

相关文章:

  • 64位ubuntu下安装32位jdk
  • response.setHeader()的用法
  • PCIE BAR空间
  • HDU5115:Dire Wolf——题解+翻译
  • JS常用代码
  • [iOS]中字体样式设置 API
  • 20个Jquery表单插件
  • MAC上Git安装与GitHub基本使用
  • ORACLE -- RAC Debug 之路 CRS-0184错误与CRS初始化
  • chrome插件控制台
  • 英特尔研发神经元AI处理器,模仿大脑功能,无需训练数据集
  • android 里使用Socket进行发送消息案例
  • 进程间通信基础知识
  • 解决Please check that your locale settings
  • 15.4. 内容监控
  • @jsonView过滤属性
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • Git同步原始仓库到Fork仓库中
  • HTTP那些事
  • Java多态
  • k8s如何管理Pod
  • Linux CTF 逆向入门
  • Linux中的硬链接与软链接
  • PHP 的 SAPI 是个什么东西
  • Sass Day-01
  • XML已死 ?
  • 阿里研究院入选中国企业智库系统影响力榜
  • 回流、重绘及其优化
  • 基于游标的分页接口实现
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 利用DataURL技术在网页上显示图片
  • 跳前端坑前,先看看这个!!
  • Nginx实现动静分离
  • zabbix3.2监控linux磁盘IO
  • 从如何停掉 Promise 链说起
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • #ifdef 的技巧用法
  • #考研#计算机文化知识1(局域网及网络互联)
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (ZT)出版业改革:该死的死,该生的生
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (二)JAVA使用POI操作excel
  • (二十四)Flask之flask-session组件
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (一)Java算法:二分查找
  • (译) 函数式 JS #1:简介
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • .FileZilla的使用和主动模式被动模式介绍
  • .gitignore
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .net core控制台应用程序初识