博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Future模式,探讨mina中的Iofuture
阅读量:4080 次
发布时间:2019-05-25

本文共 5520 字,大约阅读时间需要 18 分钟。

2010
-
02
-
09

文章分类:

在mina中有各种各样的future,如果不知道这背后的future模式,那么对mina的理解就不可能深入。

什么是future模式呢?

经常有一个线程需要得到另个一线程的计算结果,我们常用的是Future异步模式来加以解决。

Future顾名思意,有点像期货市场的“期权”,是“对未来的一种凭证”,例如当我们买了某个房地产开发商的期房,交钱之后,开发商会给我们一个凭证(期权),这个凭证告诉我们等明年某个时候拿这个凭证就可以拿到我们所需要的房子,但是现在房子还没建好。市场上之所以有“期货”,也正由于有这种需求,才有这种供给。

 

这种应用在GUI上用的比较多,在设计模式中一般称为“ ”。

Future大至的交互图:

 

详情:

 

2010
-
02
-
22

文章分类:

先了解下future是个什么东东?

以上三篇可以让你明白什么是future。

现在再来看mina中的iofuture

IoFuture.png

我们常常发现有些东西只有一部分是公共的,其他部分是个性的,于是我们把公共的东西单独抽象成一个超接口(比如这里的IoFuture),其他个性的东西,是在公共的基础上增加个性的东西,所以public interface ConnectFuture extends IoFuture;public interface ReadFuture extends IoFuture等等;同时,我们公共的东西可以公共的实现public class DefaultIoFuture implents IoFuture。然后个性的东西,在公共实现的基础上完成(重用:可以选择继承,或组合),于是public class ConnetFuture extends DefaultIoFuture implents ConnectFuture,其中extends DefaultIoFuture体现了用继承的方式重用公共的操作,implments ConnectFuture体现了在公共的基础上再去实现个性的东西。

 

如果要看Future机制的话,我们只需要了解DefaultIoFuture这个公共操作类。我们首先看下IoFuture描述了哪些功能需求:

(1)boolean isReady     判断“真实东西”是否准备完毕;

(2)await/awaitUninterruptibly  表示如果客户比较着急(可能在真实东西准备好之前就想提货),程序会阻塞客户,这里相对我前面的 中提供的措施要丰富些,用户可以选择长期阻塞await【内部最终实现是lock.wait()】,或者在一定时间内阻塞await(long timeout)【内部最终实现是lock.wait(timeout)】;

(3)addListener/removeListerner  这个东西和Future模式没有什么关系,只是个观察者模式。

(4) 中说了还需要回答一个问题是:  当真实的数据准备好的时候,真实数据怎么通知这个Future说数据好了,在DefaultIoFuture中有一个protected void setValue(object newVaule)方法,以供提供真实数据的人调用。(这里顺便提下刚才的addListener/removeListener:当Future对应的真实数据准备好时,方法setValue会被调用,那么Future接收到这个通知真实数据OK时,利用观察者模式把这个消息再向它的观察着进行广播下。)

对future有了理解,再来阅读mina的源码就相当简单明了。

在mina中有两段重点注意下的代码,值得学习。

DefaultIoFuture中:

一是等待代码

/**     * Wait for the Future to be ready. If the requested delay is 0 or      * negative, this method immediately returns the value of the      * 'ready' flag.      * Every 5 second, the wait will be suspended to be able to check if      * there is a deadlock or not.     *      * @param timeoutMillis The delay we will wait for the Future to be ready     * @param interruptable Tells if the wait can be interrupted or not     * @return true if the Future is ready     * @throws InterruptedException If the thread has been interrupted     * when it's not allowed.     */    private boolean await0(long timeoutMillis, boolean interruptable) throws InterruptedException {        long endTime = System.currentTimeMillis() + timeoutMillis;        synchronized (lock) {            if (ready) {                return ready;            } else if (timeoutMillis <= 0) {                return ready;            }            waiters++;            try {                for (;;) {                    try {                        long timeOut = Math.min(timeoutMillis, DEAD_LOCK_CHECK_INTERVAL);                        lock.wait(timeOut);                    } catch (InterruptedException e) {                        if (interruptable) {                            throw e;                        }                    }                    if (ready) {                        return true;                    } else {                        if (endTime < System.currentTimeMillis()) {                            return ready;                        }                    }                }            } finally {                waiters--;                if (!ready) {                    checkDeadLock();                }            }        }    }

 

二是检查死锁

/**     *      * TODO checkDeadLock.     *     */    private void checkDeadLock() {        // Only read / write / connect / write future can cause dead lock.         if (!(this instanceof CloseFuture || this instanceof WriteFuture ||              this instanceof ReadFuture || this instanceof ConnectFuture)) {            return;        }                // Get the current thread stackTrace.         // Using Thread.currentThread().getStackTrace() is the best solution,        // even if slightly less efficient than doing a new Exception().getStackTrace(),        // as internally, it does exactly the same thing. The advantage of using        // this solution is that we may benefit some improvement with some        // future versions of Java.        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();        // Simple and quick check.        for (StackTraceElement s: stackTrace) {            if (AbstractPollingIoProcessor.class.getName().equals(s.getClassName())) {                IllegalStateException e = new IllegalStateException( "t" );                e.getStackTrace();                throw new IllegalStateException(                    "DEAD LOCK: " + IoFuture.class.getSimpleName() +                    ".await() was invoked from an I/O processor thread.  " +                    "Please use " + IoFutureListener.class.getSimpleName() +                    " or configure a proper thread model alternatively.");            }        }        // And then more precisely.        for (StackTraceElement s: stackTrace) {            try {                Class
cls = DefaultIoFuture.class.getClassLoader().loadClass(s.getClassName()); if (IoProcessor.class.isAssignableFrom(cls)) { throw new IllegalStateException( "DEAD LOCK: " + IoFuture.class.getSimpleName() + ".await() was invoked from an I/O processor thread. " + "Please use " + IoFutureListener.class.getSimpleName() + " or configure a proper thread model alternatively."); } } catch (Exception cnfe) { // Ignore } } }

posted on 2010-06-19 10:37 阅读(...) 评论(...)

转载地址:http://lepni.baihongyu.com/

你可能感兴趣的文章
环境分支-git版本管理
查看>>
Spring AOP + Redis + 注解实现redis 分布式锁
查看>>
支付宝生活号服务号 用户信息获取 oauth2 登录对接 springboot java
查看>>
CodeForces #196(Div. 2) 337D Book of Evil (树形dp)
查看>>
uva 12260 - Free Goodies (dp,贪心 | 好题)
查看>>
uva-1427 Parade (单调队列优化dp)
查看>>
【设计模式】学习笔记14:状态模式(State)
查看>>
poj 1976 A Mini Locomotive (dp 二维01背包)
查看>>
斯坦福大学机器学习——因子分析(Factor analysis)
查看>>
linux对于没有写权限的文件如何保存退出vim
查看>>
IntelliJ IDEA 下的svn配置及使用的非常详细的图文总结
查看>>
【IntelliJ IDEA】idea导入项目只显示项目中的文件,不显示项目结构
查看>>
ssh 如何方便的切换到其他节点??
查看>>
JSP中文乱码总结
查看>>
Java实现DES加密解密
查看>>
HTML基础
查看>>
Java IO
查看>>
Java NIO
查看>>
Java大数据:Hbase分布式存储入门
查看>>
大数据学习:Spark RDD操作入门
查看>>