From #30489

It's not expected that users inject the bean and call onApplicationEvent directly. If you want to change the application availability status, you should emit an AvailabilityChangeEvent. The spring event system will then ensure that these listeners are called. And they are not called concurrently.

@mhalbritter I trace the code from AvailabilityChangeEvent, and find there is nothing to ensure that listeners are not called concurrently —— I can't find any lock or things like BlockingQueue.

// 1. multiple thread invoke this static method concurrently and publish different state.
 AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);

// 2.  call multicastEvent in ‘AbstractApplicationContext#publishEvent(Object, ResolvableType)‘
//      still don't have any lock, 
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType)

// 3. multiple thread could invoke 'SimpleApplicationEventMulticaster#multicastEvent' at same time and publish different event concurrently.
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
                 ...
        doInvokeListener(listener, event);
}

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
        listener.onApplicationEvent(event);
    }
        ...
}

Comment From: scottfrederick

@dugenkui03 Please do not open a new issue to ask a question that you've already asked in the linked issue.