2016-03-08 37 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,但它会掩盖第二类的目的。