06.EventBus异步的AsyncEventBus

一、说明

1、需要外部提供异步执行事件使用的线程池,对事件进行异步发送

2、实际上,尽管用异步的事件总线,也不应该占用事件发送线程处理事件,而应该由业务线程池处理,如netty的设计理念

二、代码

listener

package com.mzj.guava.eventbus.listeners;

import com.google.common.eventbus.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 测试异步总线listener
 */
public class AsyncSimpleListener {

    private final static Logger LOGGER = LoggerFactory.getLogger(AsyncSimpleListener.class);

    @Subscribe
    public void doAction1(final String event) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Received event [{}] and will take a action1", event);
        }
    }

    @Subscribe
    public void doAction2(final String event) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Received event [{}] and will take a action2", event);
        }
    }

    @Subscribe
    public void doAction3(final String event) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Received event [{}] and will take a action3", event);
        }
    }

    @Subscribe
    public void doAction4(final String event) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Received event [{}] and will take a action4", event);
        }
    }


}

main

package com.mzj.guava.eventbus.myeventbus;

import com.google.common.eventbus.AsyncEventBus;
import com.mzj.guava.eventbus.listeners.AsyncSimpleListener;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AsyncEventBusExample
{
    public static void main(String[] args)
    {
        AsyncEventBus eventBus = new AsyncEventBus(Executors.newFixedThreadPool(4));

//        AsyncEventBus eventBus = new AsyncEventBus(new SeqExecutor());
        eventBus.register(new AsyncSimpleListener());
        eventBus.post("hello");
    }

    static class SeqExecutor implements Executor
    {

        @Override
        public void execute(Runnable command)
        {
            command.run();
        }
    }
}

三、源码

AsyncEventBus的实现代码仅此而已:

package com.google.common.eventbus;

import com.google.common.annotations.Beta;
import java.util.concurrent.Executor;

@Beta
public class AsyncEventBus extends EventBus {

  public AsyncEventBus(String identifier, Executor executor) {
    super(identifier, executor, Dispatcher.legacyAsync(), LoggingHandler.INSTANCE);
  }

  public AsyncEventBus(Executor executor, SubscriberExceptionHandler subscriberExceptionHandler) {
    super("default", executor, Dispatcher.legacyAsync(), subscriberExceptionHandler);
  }

  public AsyncEventBus(Executor executor) {
    super("default", executor, Dispatcher.legacyAsync(), LoggingHandler.INSTANCE);
  }
}

可见,通过抽象executor,使得AsyncEventBus可以继承EventBus 进行实现

四、补充

  • google eventbus的异步特征,是由构造eventbus时提供的Executor决定的,也就是new AsyncEventBus时,如果传递个single executor或者runnable->{ runnable.run(); }的lambda,创建出来的eventbus仍然是串行的。
  • google eventbus设计上优化建议1:上面一点封装性不是太好,如果使用ExecutorService就没问题
  • google eventbus设计上优化建议2:executor使用完毕后需要外部自行关闭,最好是eventbus提供一个方法供外部调用释放资源,虽然executor是外部创建好提供的,从职责上属于外部,但是如果释放资源也由外部释放,则外部不清楚close时,eventbus处于何种状态,而如果由eventbus进行释放,可以在释放之前做准备,比如:优雅退出、发送未处理事件等等动作。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值