zoukankan      html  css  js  c++  java
  • Guava包学习--EventBus

    之前没用过这个EventBus,然后看了一下EventBus的源码也没看明白,(-__-)b。反正大概就是弄一个优雅的方式实现了观察者模式吧。慢慢深入学习一下。

    观察者模式其实就是生产者消费者的一个变种,就是一边有变化,然后有一个中介,也就是观察者去告诉消费者说:我说哥们啊,他们那边又变了,咱也跟着变吧!

    然后观察者要么就是一个抽象类或者一个接口,里面有个update方法,需要每个处理的实例去实现,然后变化的那方持有这些实例,然后挨个去通知。

    所以你也看到了,这个持有操作其实就是很不优雅的操作,所以我们用EventBus来看下这个地方到底是怎么实现的优雅的:

    可以看到其实Guava中的EventBus的代码很少,只有几个类和注解。

    注解有俩个:AllowConcurrentEvents和Subscribe,@AllowConcurrentEvents代表使用线程安全方式获得通知和@Subscribe代表这是一个订阅者,这俩注解和一起使用。

    EventBus也就是观察者角色类有两个 EventBus和AsyncEventBus,前面是同步消息,后面支持异步消息。

    DeadEvent是指没人关心的消息,可以做一下特殊处理,这个还是很有用,你可以获得有哪些消息根本没人消费过。

    Subscriber订阅者对象,具体是哪个EventBus、哪个Listener、哪个方法 3者共同决定一个Subcriber

    Dispatcher分发消息给上面那个(那些)Subscriber

    SubscriberExceptionContext 订阅者抛出的异常上下文

    SubscriberExceptionHandler 接口,处理订阅者抛出的异常

    SubscriberRegistry 订阅动作,处理订阅者注册到一个EventBus的动作

     我们来测试一下代码:

    public class EventBusMain {
        static final EventBus LINE_1St = new EventBus("first");
        static AsyncEventBus LINE_2Ed = new AsyncEventBus("second", new Executor() {
            @Override
            public void execute(Runnable command) {
                try {
                    Thread.sleep(10000L);
                    command.run();
                } catch (InterruptedException e) {
                    System.out.println(e);
                }
            }
        });
    
        public static void main(String[] args) {
            LINE_1St.register(new EventListener());
            LINE_2Ed.register(new EventListener());
    
            int cpuNums = Runtime.getRuntime().availableProcessors();
            ExecutorService executorService = Executors.newFixedThreadPool(cpuNums * 1);
    
            Thread thread1 = new Thread() {
                @Override
                public void run() {
                    PromoEvent promoEvent = genPromoEvent();
                    LINE_1St.post(promoEvent);
                }
            };
            Thread thread2 = new Thread() {
                @Override
                public void run() {
                    LINE_2Ed.post(genDimensionEvent());
                }
            };
    
            Thread thread3 = new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(5000);
                        LINE_1St.post(111);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            executorService.execute(thread1);
            executorService.execute(thread2);
            executorService.execute(thread3);
        }
    
        static PromoEvent genPromoEvent() {
            PromoEvent event = new PromoEvent(1, Lists.newArrayList(1L, 2L, 3L), System.currentTimeMillis(), 0L);
            return event;
        }
    
        static DimensionEvent genDimensionEvent() {
            DimensionEvent event = new DimensionEvent(100, Lists.newArrayList(100L, 200L, 300L), System.currentTimeMillis(), 0L);
            return event;
        }

    然后有两个自定义事件内容,基本上内容是一样的,只是用来测试:

    public class PromoEvent {
        private int activityId;
        private List<Long> productIds;
        private Long currentTime;
        private Long triedTimes;
    
        /**
         * @param activityId
         * @param productIds
         * @param currentTime
         * @param triedTimes
         */
        public PromoEvent(int activityId, List<Long> productIds, Long currentTime, Long triedTimes) {
            super();
            this.activityId = activityId;
            this.productIds = productIds;
            this.currentTime = currentTime;
            this.triedTimes = triedTimes;
        }
    
        public int getActivityId() {
            return activityId;
        }
    
        public void setActivityId(int activityId) {
            this.activityId = activityId;
        }
    
        public List<Long> getProductIds() {
            return productIds;
        }
    
        public void setProductIds(List<Long> productIds) {
            this.productIds = productIds;
        }
    
        public Long getCurrentTime() {
            return currentTime;
        }
    
        public void setCurrentTime(Long currentTime) {
            this.currentTime = currentTime;
        }
    
        public Long getTriedTimes() {
            return triedTimes;
        }
    
        public void setTriedTimes(Long triedTimes) {
            this.triedTimes = triedTimes;
        }
    
        @Override
        public String toString() {
            return "EventTest [activityId=" + activityId + ", productIds=" + productIds + ", currentTime=" + currentTime + ", triedTimes=" + triedTimes
                    + "]";
        }

    事件监听:

    public class EventListener {
        private PromoEvent lastPromoMessage = null;
        private DimensionEvent lastDimensionMessage = null;
        private DeadEvent deadEvent = null;
    
        @Subscribe
        public void listen(PromoEvent event) {
            lastPromoMessage = event;
            System.out.println("~~~~~~~~~~PromoEvent~~~~~~~~~~~~~");
            System.out.println(event.toString());
        }
    
        @Subscribe
        public void listen(DimensionEvent event) {
            lastDimensionMessage = event;
            System.out.println("----------DimensionEvent---------");
            System.out.println(event.toString());
        }
    
        @Subscribe
        public void listen(DeadEvent event) {
            deadEvent = event;
            System.out.println("===========DeadEvent=============");
            System.out.println(event.toString());
        }
    
        public PromoEvent getLastPromoMessage() {
            return lastPromoMessage;
        }
    
        public DimensionEvent getLastDimensionMessage() {
            return lastDimensionMessage;
        }
    
        public DeadEvent getDeadEvent() {
            return deadEvent;

    我们声明了两个Bus总线,用来分别存放消息体:

    static final EventBus LINE_1St = new EventBus("first");
    static AsyncEventBus LINE_2Ed = new AsyncEventBus("second", new Executor() {····});

    然后声明3个线程,分别往同步总线里面放一个消息;延迟5秒往同步线程里面放一个无效消息;然后向延迟10秒的异步线程里面放一条消息;

    然后监听器Listener分别处理这几个消息,下面是输出结果:

    ~~~~~~~~~~PromoEvent~~~~~~~~~~~~~
    EventTest [activityId=1, productIds=[1, 2, 3], currentTime=1453096744555, triedTimes=0]
    ===========DeadEvent=============
    com.google.common.eventbus.DeadEvent@4ffa5d1a
    ----------DimensionEvent---------
    EventTest [activityId=100, productIds=[100, 200, 300], currentTime=1453096744555, triedTimes=0]
    

      

  • 相关阅读:
    第一个win8应用的制作过程
    win8开发-Xaml学习笔记一
    梦想成为“老板”的第二天
    梦想成为“老板”的第一天
    HTTP请求
    linux常用命令
    HTML中常用的标签
    HTML基本结构
    记录Django的settings文件常用配置
    Oracle数据泵expdp、impdp
  • 原文地址:https://www.cnblogs.com/congsg2016/p/5135328.html
Copyright © 2011-2022 走看看