齐齐哈尔市网站建设,网站建设中 请稍后访问,后台html模板,深圳海洋网络做网站这是两部分系列的第二篇。 第一部分介绍了有状态和无状态EJB的生命周期以及并发行为。 在这篇文章中#xff0c;我将介绍Singleton EJB 。 Singleton模式可以说是最常用#xff08;有时被滥用#xff01;#xff09;的模式。 单吨又爱它#xff01; Java EE使我们无需编… 这是两部分系列的第二篇。 第一部分介绍了有状态和无状态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上使用同步来完成。 建议阅读 EJB3.2规范 干杯 翻译自: https://www.javacodegeeks.com/2014/09/ejb-3-x-lifecycle-and-concurrency-models-part-2.html