Guava异步事件总线侦听器是顺序触发的



我正在开发一个Java应用程序,该应用程序发出应该异步处理的事件,因为事件处理依赖于IO,我希望它与核心逻辑解耦。

我正在为这个用例尝试Guava EventBus。为了启用异步事件处理,我使用AsyncEventBus与缓存线程池执行器。

当触发多个事件时,事件侦听器似乎按顺序执行,尽管运行在不同的线程上。

事件生成器类

public class MyEventEmitter {
private static final Logger logger = LogManager.getLogger(MyEventEmitter.class);
private EventBus eventBus;
public MyEventEmitter(EventBus eventBus) {
this.eventBus = eventBus;
}
public void emitEvent() {
logger.info("[TEST] Emitting event");
eventBus.post("String event");
eventBus.post("String event");
eventBus.post("String event");
eventBus.post("String event");
}
}

事件监听器类


public class EventListener {
private static final Logger logger = LogManager.getLogger(EventListener.class);
private static int eventsHandled;
private EventBus eventBus;
public EventListener(EventBus eventBus) {
this.eventBus = eventBus;
this.eventBus.register(this);
}
@Subscribe
public void stringEventDelayed(String event) throws InterruptedException{
eventsHandled++;
logger.info("[TEST] Async Event START " + event);
Thread.sleep(1000);
logger.info("[TEST] Async Event END " + event);
}
}

EventBus设置

public class MainModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides
public EventListener getEventListener(EventBus eventBus){
return new EventListener(eventBus);
}
@Singleton
@Provides
public EventBus getEventBus(){
return new AsyncEventBus(Executors.newFixedThreadPool(4));
}
@Provides
public MyEventEmitter getMyEventEmitter(EventBus eventBus){
return new MyEventEmitter(eventBus);
}
}

输出日志如下:

[INFO ] 2022-06-29 19:26:22.333 [main] EventListener - [TEST] EventListener setup
[INFO ] 2022-06-29 19:26:22.345 [main] MyEventEmitter - [TEST] Emitting event
[INFO ] 2022-06-29 19:26:22.346 [pool-2-thread-1] EventListener - [TEST] Async Event START String event
[INFO ] 2022-06-29 19:26:23.348 [pool-2-thread-1] EventListener - [TEST] Async Event END String event
[INFO ] 2022-06-29 19:26:23.348 [pool-2-thread-4] EventListener - [TEST] Async Event START String event
[INFO ] 2022-06-29 19:26:24.353 [pool-2-thread-4] EventListener - [TEST] Async Event END String event
[INFO ] 2022-06-29 19:26:24.359 [pool-2-thread-3] EventListener - [TEST] Async Event START String event
[INFO ] 2022-06-29 19:26:25.361 [pool-2-thread-3] EventListener - [TEST] Async Event END String event
[INFO ] 2022-06-29 19:26:25.361 [pool-2-thread-2] EventListener - [TEST] Async Event START String event
[INFO ] 2022-06-29 19:26:26.364 [pool-2-thread-2] EventListener - [TEST] Async Event END String event

从上面可以看出,所有的异步监听器似乎都是一个接一个执行的,而不是并发执行的。

我已经尝试改变执行者类型,尝试在本地调试,并尝试搜索,但无法找到任何特定于我的问题。

From EventBus Javadocs:

EventBus保证它不会同时从多个线程调用订阅者方法,除非该方法通过携带AllowConcurrentEvents注释显式地允许它。如果该注释不存在,订阅者方法不必担心可重入,除非也从EventBus外部调用。

你应该用@AllowConcurrentEvents

注释你的订户方法

最新更新