2016-03-08 36 views
1

的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時,它不響應外部方法調用。

EJB lifecycle

回答

0

我想這個行爲與EJB中的Singleton生命週期有關。

我解決了第三個啓動bean的問題,它依賴於兩個單例,並手動調用其中一個單例的方法,當兩個單例都加載完畢。我爲此添加了start()方法。

我本可以從DeadlockReproducerAid之一開始DeadlockReproducer,但它會掩蓋第二類的目的。