为什么jfinal的控制器不用单例模式

Posted 有梦就能实现

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么jfinal的控制器不用单例模式相关的知识,希望对你有一定的参考价值。

先假controller定采用单例模式,通常两种设计方式来存放 HttpServletRequest、HttpServletResponse 等对象,一是利用一个类似于 ActionContext 的对象然后用 ThreadLocal 绑定到当前线程,这种方式仍然要创建 ActionContext 对象,空间消耗并不比jfinal现在的controler模式少;二是不将 ActionContext 实例化,而是在 ActionContext 中使用多个 ThreadLocal 分别存放  HttpServletRequest、HttpServletResponse 等等请求上下文对象,采用多个 ThreadLocal 存放和读取 request、response 等对象的性能远不如 jfinal controller中的 getRequest()、getResponse(),并且通常这些对象是需要多次获取,所以需要多次从 ThreadLocal 中获取,并且在本次请求结束后需要在 finally 块中使用 threadLocal.remove() 掉这些对象,这也会消耗性能。

     所以 Controller 做成单例,一是仍然无法避免 new 出对象来,二是从threadLocal中取数据性能远不如getter 方法,现在的服务器都是大内存,用空间换时间已成为更好的选择。

     再假设 Controller 采用非单例模式,如果在 controller 定义了属性值,天然就可以避免线程安全问题。至于内存空间消耗可以精确地计算出来,Controller 类共有八个属性,其中三个是 static 全局共享的那么 Controller 对象占用内存情况:

       Controller对象占用内存 = 对象头 + 属性指针 + 对齐填充 = 8 + 4*5 +  4 = 32Bytes

      JVM存放每个字符使用 2个字节,那么一个controller对象仅相当于一个 16 个字符的String而已。

      假定你的服务器每天接受 1亿次请求,创建 controller 需要的内存为:32Bytes * 1亿 = 2.98GB,一亿次请求创建Controller对象只需要 2.89GB内存,并且JVM 有自动回收内存的机制。相对于整个调用堆栈 controller 所占内存可以忽略不计,例如通常一次数据库访问 find(sql) 出来的数据所占内存远比多次创建 controller 对象要占用内存多得多。

以上是关于为什么jfinal的控制器不用单例模式的主要内容,如果未能解决你的问题,请参考以下文章

用JS来理解设计模式—— 单例模式

Java单例模式

使用闭包创建“单例模式”

IoDH 实现的单例模式

为什么使用单例模式?

“单例”模式-ThreadLocal线程单例