Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deadlock publishing event while creating listener bean [SPR-12739] #17336

Closed
spring-issuemaster opened this issue Feb 20, 2015 · 1 comment

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Feb 20, 2015

Mike Heath opened SPR-12739 and commented

Publishing an application event in a second thread while creating an application event listener bean causes a deadlock.

The Reference URL points to a Github gist of a simple Spring Boot app that duplicates the deadlock.

Dump of the deadlocked threads:

"main@1" prio=5 tid=0x1 nid=NA waiting for monitor entry
java.lang.Thread.State: BLOCKED
blocks executor-1@2266
waiting for executor-1@2266 to release lock on <0x919> (a org.springframework.context.event.AbstractApplicationEventMulticaster$ListenerRetriever)
at org.springframework.context.event.AbstractApplicationEventMulticaster.addApplicationListener(AbstractApplicationEventMulticaster.java:72)
at org.springframework.context.support.AbstractApplicationContext.addApplicationListener(AbstractApplicationContext.java:422)
at org.springframework.context.support.PostProcessorRegistrationDelegate$ApplicationListenerDetector.postProcessAfterInitialization(PostProcessorRegistrationDelegate.java:354)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1571)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)

  • locked <0x8ee> (a java.util.concurrent.ConcurrentHashMap)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
  • locked <0x91f> (a java.lang.Object)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at cloudfoundry.norouter.test.DeadlockTest.main(DeadlockTest.java:61)

"executor-1@2266" prio=5 tid=0xf nid=NA waiting for monitor entry
java.lang.Thread.State: BLOCKED
blocks main@1
waiting for main@1 to release lock on <0x8ee> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:187)
at org.springframework.beans.factory.support.AbstractBeanFactory.getType(AbstractBeanFactory.java:567)
at org.springframework.context.event.AbstractApplicationEventMulticaster.retrieveApplicationListeners(AbstractApplicationEventMulticaster.java:212)
at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:172)

  • locked <0x919> (a org.springframework.context.event.AbstractApplicationEventMulticaster$ListenerRetriever)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:117)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)
    at cloudfoundry.norouter.test.DeadlockTest.lambda$publisherBean$0(DeadlockTest.java:45)
    at cloudfoundry.norouter.test.DeadlockTest$$Lambda$1.1037475674.run(Unknown Source:-1)
    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:744)

Affects: 3.2.13, 4.1.4

Reference URL: https://gist.github.com/mheath/547ce1044c282acd88e6

Issue Links:

  • #17148 AbstractApplicationEventMulticaster "lost" application listener
  • #18814 Deadlock possible with AspectJ aspects and multi-threading

Backported to: 3.2.14

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 25, 2015

Juergen Hoeller commented

This has been introduced through #17148, trying to prevent the less of concurrently registered listeners in the cached retrievers.

Now addressed through using the same mutex object for locking, that is, the registry's singleton mutex is also being used by the event multicaster.

This will be available in the upcoming 4.2 snapshot and also in tomorrow's 4.1.6 and 3.2.14 snapshots. Please give it a try once available!

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.