ejb生命周期_EJB 3.x:生命周期和并发模型(第2部分)
ejb生命周期
這是兩部分系列的第二篇。 第一部分介紹了有狀態(tài)和無(wú)狀態(tài)EJB的生命周期以及并發(fā)行為。 我將在本文中介紹Singleton EJB 。
Singleton模式可以說(shuō)是最常用(有時(shí)被濫用!)的模式。
單噸又愛它!
Java EE使我們無(wú)需編寫顯式代碼(如上圖所示)即可實(shí)現(xiàn)Singleton模式。
EJB 3.1本身就是Java EE 6的一部分,因此引入了Singleton EJB。
所需要的只是在一個(gè)豆類上提供一個(gè)@ javax.ejb.Singleton (類級(jí)別)注釋(如果需要完善其他方面,還可以添加更多注釋),以將其指定為Singleton會(huì)話bean。
JVM中只有一個(gè)實(shí)例和一個(gè)Singleton EJB實(shí)例 –無(wú)論有多少客戶端訪問(wèn)它。 它不像有狀態(tài)SB(一個(gè)在整個(gè)生命周期內(nèi)附加到單個(gè)客戶端的bean實(shí)例),也不像無(wú)狀態(tài)SB(每個(gè)狀態(tài)的請(qǐng)求)一個(gè)新實(shí)例。
Singleton Session Bean的生命周期中有哪些不同的狀態(tài)?
Singleton Bean的生命周期與無(wú)狀態(tài)會(huì)話Bean相同-實(shí)際上,這是此Bean類型的簡(jiǎn)單方面之一:
- 不存在
- 準(zhǔn)備
狀態(tài)如何變化? 是什么觸發(fā)了他們?
這是一個(gè)快速的表格快照和一個(gè)高級(jí)圖表。 。 。
單例豆–狀態(tài)轉(zhuǎn)換
| DNE轉(zhuǎn)R | 首次通過(guò)JNDI / DI訪問(wèn)實(shí)例或由容器使用@Startup或@DependsOn自動(dòng)實(shí)例化實(shí)例時(shí) | @PostConstruct | 
| R到DNE | 容器關(guān)閉–銷毀bean實(shí)例,或者@PostConstruct注釋方法中發(fā)生異常 | @PreDestroy | 
注意 :DNE –不存在, R –就緒
如前所述,生命周期是Singleton bean的較簡(jiǎn)單功能之一。 了解它們的并發(fā)方面至關(guān)重要。
Singleton Session Bean:并發(fā)管理
如前所述– Singleton在JVM中只有一個(gè)實(shí)例。 在Java EE環(huán)境中,并發(fā)訪問(wèn)是不可避免的–這就是為什么我們首先使用Java EE之類的技術(shù)的原因! 需要確保根據(jù)用例和需求,仔細(xì)考慮Singleton bean的并發(fā)( 鎖定 )策略。
Singleton –小心消費(fèi)!
Singleton bean并發(fā)可以分為2個(gè)主要類別 :
- 容器托管(默認(rèn))
- Bean托管
容器管理并發(fā)
- 顧名思義,容器對(duì)Bean應(yīng)用了明智的默認(rèn)配置
- 可以使用注釋和XML(部署描述符)進(jìn)行控制
-  在bean類本身上使用@ javax.ejb.ConcurrencyManagement注釋明確聲明 - 默認(rèn)值為javax.ejb.ConcurrencyManagementType.CONTAINER
 
-  容器提供了兩種可能的鎖定策略 –適用于bean類或其單個(gè)方法 - @ javax.ejb.Lock ,其值為javax.ejb.LockType.READ –在沒有寫鎖的情況下允許并發(fā)訪問(wèn)
 
- 可以在Bean類或方法上指定@ javax.ejb.AccessTimeout以確保線程在不確定的時(shí)間段內(nèi)不會(huì)阻塞或持有鎖
Bean托管并發(fā)
- 該名稱清楚地表明– Bean的并發(fā)方面留給開發(fā)人員。 與容器通過(guò)上述構(gòu)造提供的并發(fā)控制相比,在需要更好的并發(fā)控制時(shí)有意義
- 需要使用適當(dāng)?shù)腏ava并發(fā)構(gòu)造,例如同步,易失等
- 很難正確!
代碼示例
讓我們看一個(gè)簡(jiǎn)單的代碼片段,以便更好地理解上述事實(shí):
方案一 –容器管理的并發(fā)(默認(rèn),未明確指定鎖定類型)
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觸發(fā)了2個(gè)并發(fā)線程(是的,只有兩個(gè)。這更多是演示,而不是負(fù)載測(cè)試競(jìng)賽!)
觀察結(jié)果
查看日志,可以輕松得出以下幾點(diǎn):
- Servlet當(dāng)然不是線程安全的,因此有兩個(gè)線程同時(shí)進(jìn)入
- 其中一個(gè)線程在Singleton bean類中輸入方法(標(biāo)記為紅色),由于容器強(qiáng)制使用默認(rèn)的WRITE鎖定類型 ,因此禁止進(jìn)一步訪問(wèn)
- 第一個(gè)線程完成執(zhí)行后,最初被阻塞的第二個(gè)線程(標(biāo)記為綠色)就有機(jī)會(huì)執(zhí)行Singleton bean方法
- 很簡(jiǎn)單!
方案二 –堅(jiān)持使用容器管理的并發(fā)性。 將顯式鎖定類型從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());} }當(dāng)應(yīng)用程序被2個(gè)并發(fā)線程轟炸(雙關(guān)!)時(shí),會(huì)發(fā)生什么情況。 。 。 ?
- 如預(yù)期的那樣,兩個(gè)線程同時(shí)進(jìn)入Servlet
- 線程之一進(jìn)入Singleton bean類中的方法(標(biāo)記為紅色)
- 第二個(gè)線程(標(biāo)記為綠色)也設(shè)法同時(shí)進(jìn)入Singleton bean方法(檢查時(shí)間戳記)
- 再次-非常簡(jiǎn)單!
我現(xiàn)在所描述的不是Bean管理并發(fā)。 如上所述,將BMC用于Singleton會(huì)將責(zé)任轉(zhuǎn)移給開發(fā)人員,并且他可以自由地將并發(fā)功能編碼到Bean中,這可以簡(jiǎn)單地在每種方法或其他機(jī)制(例如,從java.util.concurrent API)上使用同步來(lái)完成。
建議閱讀
- EJB(3.2)規(guī)范
干杯!
翻譯自: https://www.javacodegeeks.com/2014/09/ejb-3-x-lifecycle-and-concurrency-models-part-2.html
ejb生命周期
總結(jié)
以上是生活随笔為你收集整理的ejb生命周期_EJB 3.x:生命周期和并发模型(第2部分)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 低电量模式伤害电池吗 苹果手机的低电量模
- 下一篇: JDK 14 / JEP 305模式匹配
