欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

你知道如何写一个框架吗?详细步骤放送(1)(10)

来源: javaer 分享于  点击 7937 次 点评:252

检查线程安全

框架对多线程环境支持的是否好,是框架质量的一个重要的评估标准,往往可以看到甚至有一些成熟的框架也会有多线程问题。这里涉及几个方面:

1,你无法预料框架的使用者会怎么样去实例化和保存你的API的入口类,如果你的入口类被用成为了一个单例,在并发调用的情况下会不会有单线程问题?

这是一个老话题,之前已经说过很多次,你在设计框架的时候心里如果把一个类定位成了单例的类但却没有提供单例模式,你是无法要求使用者来帮你实现单例的。这其中涉及的不仅仅是多线程问题,可能还有性能问题。比如见过某分布式缓存的客户端的CacheClient在文档中要求使用者针对一个缓存集群保持一个CacheClient的单例因为其中有了连接池),但是用的人还是每一次都实例化了一个CacheClient出来,几小时后就会产生几万个半死的Socket导致网络奔溃。又见过某类库的入口工厂的代码注释中写了要求使用的人把XXXFactory作为单例来使用因为其中缓存了大量数据),但是用的人就没有注意到这个注释,每一次都实例化了一个XXXFactory,造成GC的崩溃。所以我觉得作为框架的设计者开发人员,最好还是把框架的最佳实践直接做到API中,使得使用者不可能出错之前说过一句话,再重复一次,好的框架不会让使用的人犯错)。你可能会说对于CacheClient的例子,不可能做成单例的,因为我的程序可能需要用到多个缓存的集群,换个思路,我们完全可以在封装一层,通过一个CacheClientCreator之类的类来管理多个单例的CacheClient。即使在某些极端的情况下,你不能只提供一条路给使用者去走,也需要在框架内做一些检测机制,及时提醒使用者 "我们发现您这样使用了框架,这可能会产生问题,你本意是否打算那样做呢?"

2,如果你的入口类本来就是单例的,那么你是类中是否持有共享资源,你的API在并发的情况下被调用是否可以确保这些资源的线程安全?在解决多线程问题的时候往往有几个难点:

百密难有一疏,你很难想到这段代码会有人这样去并发调用。比如某init()方法,某config()方法,你总是假设使用者会调用并且仅调用一次,但事实不一定这样,有的时候调用者自己也不清楚我的容器会调用我这段代码多少次。
好吧,解决多线程问题各种烦躁,那就对各种涉及到共享资源的方法全部加锁。对方法进行粗犷粒度)的锁可能会导致性能急剧下降甚至是死锁问题。
自以为使用了优雅的无锁代码或并发容器但却达不到目的。我们往往在大量使用了并发集合心中暗自窃喜解决了多线程问题的同时又达到了极佳的性能,但你以为这样是解决了线程安全问题但其实根本就没有,我们不能假设A和B都方法是线程安全的,但对A和B方法调用的整个代码段是线程安全的。

对于多线程问题,我没有好的解决办法,不过下面的几条我觉得可以尝试:

需要非常仔细的过一遍代码,把涉及到共享资源的地方,以及相关的方法和类列出来,不要去假设什么,只要API暴露出去了则假设它可能被并发调用。共享资源不一定是静态资源,哪怕资源是非静态的,在并发环境下对相同对象的资源进行操作也可能产生问题。
一般而言对于公开的API,作为框架的设计者我们需要确保所有的静态方法或但单例类的实例方法)是线程安全的,对于实例方法我们可以不这么做因为性能原因),但是需要在注释中明确提示使用者方法的非线程安全,如果需要并发调用请自行处理线程安全问题。
可以看看是否有可能让这些资源字段)变为方法内的局部变量,有的时候我们并不是真正的需要类持有一个字段,只是因为多个方法要使用相同的东西,随手一写罢了。
对于使用频率低的一些方法相关的一些资源没有必要使用并发容器,直接采用粗狂的方式进行资源加锁甚至是方法级别加锁,先确保没有线程安全,如果以后做压测出现性能问题再来解决。
对于使用频率高的一些方法相关的一些资源可以使用并发容器,但需要仔细思考一下代码是否会存在线程安全问题,必要的话为代码设计一些多线程环境的单元测试去验证。


性能测试和优化

之前也提到过,你不会预测到你的项目会在怎么样的访问量下使用,我们不希望框架和同类的框架相比有明显的性能差距如果你做的是一个ORM框架或RPC框架,这个工作就是必不可少的),所以在框架基本完成后我们需要做Benchmark:

封装和扩展

个人觉得一个框架如果只是能用那是第一个层次,能很方便的进行扩展或二次开发那是另外一个层次,如果我们龙骨阶段的工作做的足够好,框架是一个立体饱满的框架,那么这部分的工作量就会小很多,否则我们需要对框架进行不少的重构以便可以达到这个层次。




相关栏目:

用户点评