这是两部分系列的第二篇。 第一部分介绍了有状态和无状态EJB的生命周期以及并发行为。 在这篇文章中,我将介绍Singleton EJB

Singleton模式可以说是最常用(有时被滥用!)的模式。

单吨又爱它!

Java EE使我们无需编写显式代码(如上图所示)即可实现Singleton模式。

EJB 3.1本身就是Java EE 6的一部分,因此引入了Singleton EJB。

所需要的只是在一个豆类上提供一个@ javax.ejb.Singleton (类级别)注释(如果需要完善其他方面,还可以添加更多注释),以将其指定为Singleton会话bean。

JVM中只有一个实例和一个Singleton EJB实例 –无论有多少客户端访问它。 它不像有状态SB(一个在整个生命周期内附加到单个客户端的bean实例),也不像无状态SB(每个状态),每个客户端请求都有一个新实例。

Singleton Session Bean的生命周期中有哪些不同的状态?

Singleton Bean的生命周期与无状态会话Bean相同-实际上,这是此Bean类型的简单方面之一:

  • 不存在
  • 准备

状态如何变化? 是什么触发了他们?

这是一个快速的表格快照和一个高级图表。 。 。

单例豆–状态转换

国家过渡 扳机 回呼
DNE转R 首次通过JNDI / DI访问实例或由容器使用@Startup或@DependsOn自动实例化实例时 @PostConstruct
R到DNE 容器关闭–销毁bean实例,或者@PostConstruct注释方法中发生异常 @PreDestroy

注意 :DNE –不存在, R –就绪

如前所述,生命周期是Singleton bean的较简单功能之一。 了解它们的并发方面至关重要。

Singleton Session Bean:并发管理

如前所述– Singleton在JVM中只有一个实例。 在Java EE环境中,并发访问是不可避免的–这就是为什么我们首先使用Java EE之类的技术的原因! 需要确保根据用例和需求,仔细考虑Singleton bean的并发( 锁定 )策略。

Singleton –小心消费!

Singleton bean并发可以分为2个主要类别

  • 容器托管(默认)
  • Bean托管

容器管理并发

  • 顾名思义,容器为Bean应用了明智的默认配置
  • 可以使用注释和XML(部署描述符)进行控制
  • 在bean类本身上使用@ javax.ejb.ConcurrencyManagement注释明确声明
    • 默认值为javax.ejb.ConcurrencyManagementType.CONTAINER
  • 容器提供了两种可能的锁定策略 –适用于bean类或其单个方法
    • @ javax.ejb.Lock ,值为javax.ejb.LockType.READ-允许在没有写锁的情况下进行并发访问
  • 可以在Bean类或方法上指定@ javax.ejb.AccessTimeout,以确保线程在不确定的时间段内不会阻塞或持有锁

Bean托管并发

  • 该名称清楚地表明– Bean的并发方面留给开发人员。 与容器通过上述构造提供的并发控制相比,需要更好的并发控制是有意义的
  • 需要使用适当的Java并发构造,例如同步,易失等
  • 很难正确!

代码示例

让我们看一个简单的代码片段,以便更好地理解上述事实:

方案一 –容器管理的并发(默认,未明确指定锁定类型)

package com.abhirockzz.wordpress.ejb.lifecycle.singleton;import com.abhirockzz.wordpress.ejb.lifecycle.stateful.MyStatefulBean;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Singleton;
import javax.ejb.Startup;@Singleton
@Startup
public class MySingletonBean {public void act() {System.out.println("Entered MySingletonBean/act() on " + new Date().toString() + " . Singleton instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException ex) {Logger.getLogger(MyStatefulBean.class.getName()).log(Level.SEVERE, null, ex);}System.out.println("Exit MySingletonBean/act() on " + new Date().toString() + " . Singleton instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());}
}
package com.abhirockzz.wordpress.ejb.lifecycle.singleton;import java.io.IOException;
import java.util.Date;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet(name = "SingletonTestServlet", urlPatterns = {"/SingletonTestServlet"})
public class SingletonTestServlet extends HttpServlet {public SingletonTestServlet() {}@InjectMySingletonBean mySingleton;@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("Entered SingletonTestServlet/doGet() on " + new Date().toString() + " . Servlet instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());mySingleton.act();}}

使用Apache JMeter –我在SingletonTestServlet触发了2个并发线程(是的,只有两个。这更多是演示,而不是负载测试竞赛!)

观察结果

查看日志,可以轻松得出以下几点:

  • Servlet当然不是线程安全的,因此两个线程同时进入
  • 其中一个线程在Singleton bean类中输入方法(标记为红色),并且由于容器强制使用默认的WRITE锁定类型 ,因此禁止进一步访问
  • 第一个线程完成执行后,最初被阻塞的第二个线程(标记为绿色)就有机会执行Singleton bean方法
  • 很简单!

方案二 –坚持容器管理的并发性。 将显式锁定类型从WRITE更改为READ

import com.abhirockzz.wordpress.ejb.lifecycle.stateful.MyStatefulBean;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;
import javax.ejb.Startup;@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class MySingletonBean {@Lock(LockType.READ)public void act() {System.out.println("Entered MySingletonBean/act() on " + new Date().toString() + " . Singleton instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException ex) {Logger.getLogger(MyStatefulBean.class.getName()).log(Level.SEVERE, null, ex);}System.out.println("Exit MySingletonBean/act() on " + new Date().toString() + " . Singleton instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());}
}

当应用程序被2个并发线程轰炸(双关!)时,会发生什么情况。 。 。 ?

  • 如预期的那样,两个线程同时进入Servlet
  • 线程之一进入Singleton bean类中的方法(标记为红色)
  • 第二个线程(标记为绿色)也设法同时进入Singleton bean方法(检查时间戳记)
  • 再次-非常简单!

我现在所描述的不是Bean管理并发。 如上所述,将BMC用于Singleton会将责任转移给开发人员,并且他可以自由地将并发功能编码到Bean中,这可以简单地在每种方法或其他机制(例如,从java.util.concurrent API)上使用同步来完成。

建议阅读

  • EJB(3.2)规范

干杯!

翻译自: https://www.javacodegeeks.com/2014/09/ejb-3-x-lifecycle-and-concurrency-models-part-2.html

EJB 3.x:生命周期和并发模型(第2部分)相关推荐

  1. ejb生命周期_EJB 3.x:生命周期和并发模型(第2部分)

    ejb生命周期 这是两部分系列的第二篇. 第一部分介绍了有状态和无状态EJB的生命周期以及并发行为. 我将在本文中介绍Singleton EJB . Singleton模式可以说是最常用(有时被滥用! ...

  2. ejb生命周期_EJB 3.x:生命周期和并发模型(第1部分)

    ejb生命周期 对于经验丰富的专业人员来说,Java EE组件生命周期和与并发相关的详细信息可能不是新知识,但是对于初学者来说,这可能会花费一些时间. 就EJB而言,了解其生命周期 (以及相关的并发场 ...

  3. EJB 3.x:生命周期和并发模型(第1部分)

    Java EE组件生命周期和与并发相关的详细信息对于经验丰富的专业人员而言可能不是新知识,但是对于初学者而言,这可能需要花费一些时间. 就EJB而言,了解其生命周期 (以及相关的并发场景)对于确保使用 ...

  4. 软件开发生命周期及开发模型

    软件开发生命周期 软件开发生命周期又叫做SDLC(Software Development Life Cycle),它是集合了计划.开发.测试和部署过程的集合.如下图所示 : 需求分析 这是生命周期的 ...

  5. 软件测试(概念Ⅱ) · 开发模型 · 软件的生命周期 · 瀑布模型 · 螺旋模型 · 增量模型 · 迭代模型 · 敏捷模型 · scrum · 软件测试模型之 V 模型 W 模型

    一.开发模型的由来 二.软件的生命周期 三.瀑布模型(Waterfall Model) 四.螺旋模型(Spiral Model) 五.增量模型(Incremental Model) 六.迭代模型(Ra ...

  6. 二、软件工程 / 生命周期 / 软件开发模型

    软件测试 软件危机和软件工程 软件生命周期 软件生命周期模型 1. 瀑布模型 2. 螺旋模型 3. 迭代模型 4. 敏捷开发(Scrum)模型 5. 增量模型 6. 快速原型模型 软件危机和软件工程 ...

  7. Java并发编程|第二篇:线程生命周期

    文章目录 系列文章 1.线程的状态 2.线程生命周期 3.状态测试代码 4.线程终止 4.1 线程执行完成 4.2 interrupt 5.线程复位 5.1interrupted 5.2抛出异常 6. ...

  8. ejb生命周期_无状态EJB:池化和生命周期

    ejb生命周期 无状态EJB池和生命周期的概述视图(注释). 对新手有用. . . . . EJB池:快速概述 EJB实例存储在称为EJB池的位置-这不过是内存中的缓存 . 无状态EJB通常按需实例化 ...

  9. 无状态EJB:池化和生命周期

    无状态EJB池和生命周期的摘要视图(注释). 对新手有用. . . . . EJB池:快速概述 EJB实例存储在称为EJB池的位置–这不过是内存中的缓存 . 无状态EJB通常按需实例化,即,当客户端调 ...

最新文章

  1. Linux常用命令汇总(持续更新中)
  2. 综合技术 --myBatis理解
  3. 2021湖南高考艺考成绩查询,2021届湖南艺考生联考成绩查询时间安排
  4. Elasticsearch相关软件安装
  5. 实现Linux select IO复用C/S服务器代码
  6. 《软件需求分析(第二版)》第 4 章——需求分析员的职责 重点部分总结
  7. Nginx并发数、每秒连接数、下载速度限制,防攻击杀手锏
  8. Collections.sort new Compartor 用法
  9. 删除整个目录(API)
  10. 设windows 2003远程访问服务器
  11. 苹果手机上网很慢_手机的信号满格,为什么上网速度却很慢?一招教你解除限制...
  12. 原生js实现快速排序
  13. android的app,用java程序开发
  14. 计算机程序创始人阿达洛芙莱斯
  15. ZOOM一直显示登录失败,出现Zoom登录失败:100000503,zoom登录失败错误代码1044
  16. java 过期策略实现_Redis过期策略和内存淘汰机制
  17. pytorch yolov5 onnx推理
  18. 软件测试工程师规划需要学什么技能?资深测试分析总结......
  19. joomla模板的应用
  20. 批量处理数据的三种方式

热门文章

  1. 16-1 Redis分布式缓存引入与保存缓存功能实现
  2. IDEA导入Maven项目,pom.xml文件中 有inspects a maven model for resolution problems报错 !!!!!!!!!!有用
  3. kali mysql停止服务器_MySQL 的主从复制(高级篇)
  4. IDEA集成maven流程图详细介绍
  5. java 管理多个进程_管理多个Java安装
  6. lombok_Lombok–您绝对应该尝试一下
  7. neo4j 显示名字_Neo4j:绘制“我的名字是……我在工作”图
  8. jhipster_JHipster入门,第2部分
  9. java代码初体验_第一次Java 8体验
  10. JUnit5 TestSuite替代