J2EE底层是多线程的,无论何种资源管理的策略都是与线程相关的,因此通过合理的资源管理来应对多线程的环境是非常关键的。现在总结一下几种J2EE中常见的资源管理方式:

实例池
    容器管理的单例
    每个请求一个实例
    ThreadLocal策略

第一种:实例池

实例池管理策略就是通过将我们的业务组件的实例保存到池中,这样可以达到重用的目的。说到实例池,需要明确一下单线程模型的概念,所谓单线程模型就是一个实例在某一时间只能服务于同一个线程,单线程模型使得无状态的业务组件不需要关注复杂的线程问题(通俗点讲,单线程模型使得业务开发人员可以采用不需要显示的同步机制来编写业务组件代码,但是业务组件可以安全的运行与多线程环境之下)。如果采用实例池将有助于实现单线程模型。比如EJB对于无状态的会话 bean的管理就采取的是实例池的管理策略,这样以来我们的SLSB中是不需要同步的(这也是为什么EJB组件中不能有显示的同步代码的原因,因为EJB 本来就是单线程的模型),从而减轻了业务开发人员的负担。
下面总结一下这种方法的优缺点:
优点:
1 采用实例池可以使得无状态的业务组件不需要同步,这样就减轻了业务开发人员的负担。
2. 采用实例池可以限制并发执行的线程的数量,当实例池没有可用的实例可用时,线程就需要挂起,这样防止大的并发对服务器造成的压力。
缺点:
1 因为采用了实例池,增加了管理实例池的开销,增加了系统的复杂性。
2 采用实例池还是没有从根本上解决线程的问题,因为虽然实例池的实例不用同步,但是实例池的实例需要其它的组件来协作,这样其它组件的实例还是需要同步的。
具体的应用:
EJB的无状态会话bean,数据库连接池技术,TCP连接技术,web容器和ejb容器的线程池等。
PS:面向模式的软件体系结构-卷3对“实例池”有详细的描述。
第二种:容器管理的单例
 目前各种IOC容器一般都采取了此种概念,系统只维护一个无状态业务组件的实例。比如目前流行的IOC容器(spring,Picocontainer 等),它们都有将业务组件设置为单例的功能。这样以来减轻了维护实例池的开销,并且通过容器可以管理组件的生命周期,不是像以前那样用完了就丢给垃圾收集器,从而减轻了一些复杂的初始化的开销。
下面是此种方式的优缺点:
优点:
1. 减轻了一些需要复杂初始化的实例创建开销,从而提高了系统性能。
2. 通过IOC进行了组件的生命周期管理,减低了开发人员的负担。
缺点:
1 需要我们业务人员确保每个实例是无状态的,如果业务组件是有状态的,那么就要进行显示的同步,而多线程编程不是每个业务开发人员都能胜任的。
2 任意多的线程都可以进行并发调用,这样以来服务器也许无法应对巨大的负载而崩溃。
具体的应用:
目前的Servlet规范就采用一个实例(抛弃了以前的servlet单线程模型)来服务于多线程调用,这样我们必须确保servlet内部的线程安全性。
各种IOC容器(spring,Picocontainer等)
第三种:每个请求一个实例
  每个请求一个实例也是一种比较常用的方式,对于一些初始化不是很复杂的实例,我们就可以采用这种方法。采用这种方式得力与JVM性能的改进,在以前垃圾收集器算法还不成熟的时候,如果采用这种方式将会对系统性能产生很大的影响。但是现在垃圾收集器算法优化已经抵消了一定的开销。比如表现层框架 webwork、struts2,它们的xwork内核就是在每个请求过来,都新建一个命令实例(action),目前也没有出现严重的性能问题。
下面总结一下此种方式的优缺点:
优点:
1 因为是每个请求(也就是每个线程)一个实例,那么业务开发人员就不需要对业务对象进行显示的同步,这样减轻了业务开发人员的负担。
缺点:  
1 对于一些需要复杂初始化的实例,这样会给系统性能带来负面的影响。
具体的应用:
Webwork以及struts2的action都采取如此的策略,以及spring框架的prototype方式。
第四种:ThreadLocal策略
  此种策略在J2EE中也是比较常用的。它是以线程管理来驱动我们的资源管理的方式,每个线程都独自保存面向自己的变量,这样以来就可以避免多线程访问造成对 共享变量的破坏。比如hibernate中,当我们采用JDBC事务的时候,配置 hibernate.current_session_context_class=thread,内部就将当前的session与线程绑定,这样以来在同一个线程中操作将是当前绑定的session。还比如webwork中对于ActionContext的管理也采取了Treadlocal的策略,这样以来ActionContext(action的执行上下文)就与当前线程绑定(具体实现是采用一个ActionContext内部类来实现,以前看的源代码,记得不是很清楚了。。),避免多线程访问带来的复杂性。

以上的各种策略看起来是资源管理的策略,但是它们都是与多线程环境有密切关系的,每一种都有自己的优点和缺点,虽然目前框架已经为我们做好了资源管理工作,但是理解它们管理的方式对于业务开发人员还是大有裨益的。以上这些策略也是目前J2EE中常用的,不能确定那个方案比较好,具体的问题具体分析才是上上策。


实例池就是对象池,对象池在线程安全方面比单例要好些,但是 Java并发线程一书作者反对中小规模的类使用对象池,大类包括复杂系统业务类可以使用Object Pool,因为OP本身也有开销,另外一定要使用成熟的OP,不能自己编,因为线程安全很重要。
    每个请求一个单例会造成大量内存垃圾,特别是并发高情况下,这其实就是OP使用的原因,Struts2等性能不好,特别是高并发,也是这个原因。
    ThreadLocal除了框架内部使用,一般不推荐JEE应用使用,不要直接去接触线程。
    除了每个请求一个单例,还有Session,一个客户端一个单例。
    谈到单例,就一定要注意线程安全,这两者是矛盾的两个方面,为避免线程安全,struts2等就是要请求单例,但是这回引起大量小类的内存开销,这是 FlyWeight模式诞生原因,所以,回避线程安全这条路并不能带来高性能,只有面对线程安全锁,正确处理它,才是高性能的唯一之道。
    反过来说,如果能够回避,我们都是由请求单例,都用New,那多美妙简单,何必去研究复杂的锁呢?

转载于:https://blog.51cto.com/zlfwmm/1620569

J2EE常用资源管理方式总结相关推荐

  1. jQuery中ajax的4种常用请求方式

    jQuery中ajax的4种常用请求方式:1.$.ajax()返回其创建的 XMLHttpRequest 对象. $.ajax() 只有一个参数:参数 key/value 对象,包含各配置及回调函数信 ...

  2. python-django-ORM,常用查询方式

    介绍django model 的一些常用查询方式 首先是一些文档性的帮助 __exact 精确等于 like 'aaa' __iexact 精确等于 忽略大小写 ilike 'aaa' __conta ...

  3. spring中的依赖注入——构造函数注入、set方法注入( 更常用的方式)、复杂类型的注入/集合类型的注入

    spring中的依赖注入 依赖注入: Dependency Injection IOC的作用:降低程序间的耦合(依赖关系) 依赖关系的管理:以后都交给spring来维护.在当前类需要用到其他类的对象, ...

  4. 服务幂等以及常用实现方式

    现在稍具规模的网站和大型应用都不再是单机模式,而是分布式应用,基于多机的集群构建的应用,这样服务能力就可以基本实现横向扩容(scale out),不会像单机模式下的纵向扩容(scale up)会受到单 ...

  5. matplotlib.pyplot常用画图方式函数封装(一)——.plot绘制折线图及设置坐标轴箭头完美解决

    matplotlib.pyplot常用画图方式函数封装(一)--.plot绘制折线图及设置坐标轴箭头完美解决 py.plot常见绘图设置函数封装 绘制函数图像(完美解决坐标轴添加箭头) 绘制折线图 p ...

  6. Python必备收藏!Pycharm 常用快捷键方式!让鼠标离手操作

    前言 学习python中有什么不懂的地方,小编这里推荐加小编的python学习群:895,817, 687 有任何不懂的都可以在里面交流,还有很好的视频教程pdf学习资料,大家一起学习交流! 废话不多 ...

  7. 找到你的位置(JS在页面中的位置)最常用的方式是在页面中head部分放置script元素,浏览器解析head部分就会执行这个代码,然后才解析页面的其余部分...

    找到你的位置(JS在页面中的位置) 我们可以将JavaScript代码放在html文件中任何位置,但是我们一般放在网页的head或者body部分. 放在<head>部分 最常用的方式是在页 ...

  8. QT学习笔记(七):定时器事件的3种常用使用方式

    QT学习笔记(七):定时器事件的2种常用使用方式 Qt中定时器的使用有2种方法:一种是使用QObject类提供的定时器通过重载 timerEvent 事件处理过程函数,一种就是使用QTimer类. 其 ...

  9. router vue 回到顶部_小猿圈HTML5学习之基于iview的router常用控制方式

    对于互联网发展的今天,IT行业慢慢变成大多数年轻人发展的目标,不仅前景好,薪资也是越来越高的,而web前端是行业中需要的技术,也促进了大多数朋友在学习html5,今天小猿圈讲师给你分享基于iview的 ...

最新文章

  1. ASCII和字母的转换
  2. python微服务监控_如何用zabbix监控微服务
  3. 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序...
  4. UML学习笔记(4)——类图之间的关系
  5. careercup-高等难度 18.6
  6. 添加右键菜单_如何在Windows文件夹的右键菜单中添加“打开PowerShell”
  7. *【CodeForces - 1088 ABC】套题比赛,A水题B模拟C构造D交互
  8. Unity Shader 之 透明效果
  9. syslog工具_07 Docker 可视化管理和监控工具
  10. XEON® Scalable-如何为虚拟化挑选合适的CPU
  11. 谁在阻止RSS的普及??
  12. 西门子S7-200 SMART编程软件下载
  13. woocommerce修改商品详情页
  14. windows 好用软件推荐
  15. https免费泛域名证书申请
  16. 部署scrapy爬虫到AWS Ubuntu 18.04,用crontab定时执行
  17. 跨层中介作用模型2-1-1的Mplus语法
  18. Paddle2.0让你成为诗词大师-PaddlePoetry
  19. 数据库Geometry字段操作
  20. 物流企业竞争优势及竞争力体系的构建 (zt)

热门文章

  1. REM+SVG Sprite,web app案例
  2. 莫德友_去哪儿酒店交易系统架构实践
  3. ipch文件夹和.sdf文件
  4. 【OpenCV学习】XML的读写
  5. 学习笔记(3.29)
  6. P3879 [TJOI2010]阅读理解 [STL]
  7. Python: 没有switch-case语句
  8. 万众瞩目,2018中国企业数字化转型国际峰会,重磅来袭
  9. exchange 2013 升级CU15,提示“上次安装完成后没有重启”的提示
  10. [9-1]磁盘基本知识、分区基本概念