的EJB相互調用我有在tomee運行死鎖兩個單身
他們呼籲彼此2 EJB @Singleton
秒,就有一個死鎖
@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DeadlockReproducer {
private final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_STARTUP_CONFIG, this.getClass());
@EJB
private DeadlockReproducerAid deadlockReproducerAid;
@PostConstruct
public void reproduce(){
LOGGER.info("reproduce");
deadlockReproducerAid.lockMe();
}
public void youCantGetMe(){
LOGGER.info("youCantGetMe");
}
}
@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DeadlockReproducerAid {
private final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_STARTUP_CONFIG, this.getClass());
@EJB
DeadlockReproducer deadlockReproducer;
public void lockMe(){
LOGGER.info("lockMe");
deadlockReproducer.youCantGetMe();
}
}
我得到一個死鎖時youCantGetMe是等待重現返回。
這裏是堆棧跟蹤:
"localhost-startStop-1" #68 daemon prio=5 os_prio=0 tid=0x0000000056d1f000 nid=0x14e0 waiting on condition [0x0000000058aab000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fc7a2cc8> (a java.util.concurrent.FutureTask)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
at java.util.concurrent.FutureTask.get(FutureTask.java:191)
at org.apache.openejb.core.singleton.SingletonInstanceManager.getInstance(SingletonInstanceManager.java:112)
at org.apache.openejb.core.singleton.SingletonContainer.invoke(SingletonContainer.java:200)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:308)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:303)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:92)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:308)
at com.company.test.eu.logic.server.stateMachine.DeadlockReproducer$$LocalBeanProxy.youCantGetMe(com/company/test/eu/logic/server/stateMachine/DeadlockReproducer.java)
at com.company.test.eu.logic.server.stateMachine.DeadlockReproducerAid.lockMe(DeadlockReproducerAid.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:192)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:173)
at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:181)
at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:192)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:173)
at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:85)
at org.apache.openejb.core.singleton.SingletonContainer._invoke(SingletonContainer.java:256)
at org.apache.openejb.core.singleton.SingletonContainer.invoke(SingletonContainer.java:212)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:308)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:303)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:92)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:308)
at com.company.test.eu.logic.server.stateMachine.DeadlockReproducerAid$$LocalBeanProxy.lockMe(com/company/test/eu/logic/server/stateMachine/DeadlockReproducerAid.java)
at com.company.test.eu.logic.server.stateMachine.DeadlockReproducer.reproduce(DeadlockReproducer.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:192)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$LifecycleInvocation.invoke(ReflectionInvocationContext.java:223)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:173)
at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:181)
at org.apache.openejb.monitoring.StatsInterceptor.PostConstruct(StatsInterceptor.java:109)
at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:192)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:173)
at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:85)
at org.apache.openejb.BeanContext.newInstance(BeanContext.java:1590)
at org.apache.openejb.core.singleton.SingletonInstanceManager.createInstance(SingletonInstanceManager.java:179)
at org.apache.openejb.core.singleton.SingletonInstanceManager.access$100(SingletonInstanceManager.java:69)
at org.apache.openejb.core.singleton.SingletonInstanceManager$1.call(SingletonInstanceManager.java:120)
at org.apache.openejb.core.singleton.SingletonInstanceManager$1.call(SingletonInstanceManager.java:118)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.openejb.core.singleton.SingletonInstanceManager.getInstance(SingletonInstanceManager.java:129)
at org.apache.openejb.core.singleton.SingletonInstanceManager.initialize(SingletonInstanceManager.java:93)
at org.apache.openejb.core.singleton.SingletonInstanceManager.start(SingletonInstanceManager.java:84)
at org.apache.openejb.core.singleton.SingletonContainer.start(SingletonContainer.java:125)
at org.apache.openejb.assembler.classic.Assembler.startEjbs(Assembler.java:1168)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:807)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:623)
at org.apache.tomee.catalina.TomcatWebAppBuilder.startInternal(TomcatWebAppBuilder.java:1248)
at org.apache.tomee.catalina.TomcatWebAppBuilder.configureStart(TomcatWebAppBuilder.java:1087)
at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:130)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5378)
- locked <0x00000000e1115938> (a org.apache.catalina.core.StandardContext)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
- locked <0x00000000e1115938> (a org.apache.catalina.core.StandardContext)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1083)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1880)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- <0x00000000fb344d08> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync)
- <0x00000000e0bca828> (a java.util.concurrent.ThreadPoolExecutor$Worker)
當public void reproduce()
由@PostConstruct
註釋叫他們陷入僵局。
當它被另一個bean調用時,youCantGetMe
會返回。
例如,下面的設置工作:
@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DeadlockReproducer {
private final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_STARTUP_CONFIG, this.getClass());
@EJB
private DeadlockReproducerAid deadlockReproducerAid;
//@PostConstruct - no postconstruct now
public void reproduce(){
LOGGER.info("reproduce");
deadlockReproducerAid.lockMe();
}
public void youCantGetMe(){
LOGGER.info("youCantGetMe");
}
}
@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DeadlockReproducerAid {
private final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_STARTUP_CONFIG, this.getClass());
@EJB
DeadlockReproducer deadlockReproducer;
public void lockMe(){
LOGGER.info("lockMe");
deadlockReproducer.youCantGetMe();
}
}
@Startup
@Singleton
public class DeadlockInvoker {
@EJB
DeadlockReproducer deadlockReproducer;
@PostConstruct
public void startup(){
deadlockReproducer.reproduce();
}
}
它爲什麼可以和我怎樣才能使它不訴諸外部調用的伎倆工作?
編輯:
我開始弄清楚,這種行爲與EJB中的生命週期辛格爾頓做。
單身人士沒有達到Ready
狀態,直到@PostConstruct
完成運行,並且可能當它的狀態不是Ready
時,它不響應外部方法調用。