Java 设计模式 | 事件驱动 优化

优化事件总线的实现。

首先,哈希Map的线程安全问题,并建议使用ConcurrentHashMap。

执行回调时的性能瓶颈,通过多线程和线程池来提高效率。实现事件的订阅和取消订阅功能,以及如何处理同步与异步执行的需求。

最后,代码的安全性和用户体验的提升,展示了同步与异步的区别。

优化代码

package com.mgiot.application.EventEmitterCore;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @program: device-platform
 * @description:
 * @author: 
 * @create: 2024-08-26 08:48
 **/
public class EventEmitter {

    private final Map<String, List<Callback>> eventBus = new ConcurrentHashMap<>();

    private static final ExecutorService threadPoll = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    public EventEmitter emit(boolean async, String eventName, Object ...args) {
        if(!checkEmitter(eventName)) {
            return this;
        }

        List<Callback> callbackList = eventBus.get(eventName);

        if(callbackList.isEmpty()) {
            return this;
        }

        Runnable task = new Runnable() {
            @Override
            public void run() {
                callbackList.forEach(callback -> {
                    if(callback instanceof ArgsCallback argsCallback) {
                        argsCallback.invoke(args);
                        return;
                    }
                    ((NoArgsCallback)callback).invoke();
                });
            }
        };

        /*在某些情况下,开发者需要保证任务的同步执行,以避免在交给其他线程处理时出现错误或遗漏。*/
        if(async) {
            task.run();
            return this;
        }

        // 多线程 异步执行
        threadPoll.execute(task);

        return this;
    }

    // 默认采用线程池的方法
    public EventEmitter emit(String eventName, Object ...args) {
        return emit(false, eventName, args);
    }

    private boolean checkEmitter(String eventName) {
        if (!eventBus.containsKey(eventName)) {
            eventBus.put(eventName, new LinkedList<>());
            return false;
        }
        return true;
    }

    public EventEmitter on(String eventName, Callback callback) {
        checkEmitter(eventName);

        eventBus.get(eventName).add(callback);
        return this;
    }

    public EventEmitter on(String eventName, NoArgsCallback noArgsCallback) {
        return on(eventName, (Callback)noArgsCallback);
    }

    public EventEmitter on(String eventName, ArgsCallback argsCallback) {
        return on(eventName, (Callback)argsCallback);
    }

    // 取消订阅
    public EventEmitter remove(String eventName, Callback callback) {
        if(!eventBus.containsKey(eventName)) {
            return this;
        }

        eventBus.get(eventName).remove(callback);
        return this;
    }

    // 移除事件
    public EventEmitter remove(String eventName) {
        eventBus.remove(eventName);
        return this;
    }

}

执行

 public static void main(String[] args) {

        EventEmitter emitter = new EventEmitter();

        new Thread(new Runnable() {
            @Override
            public void run() {
                int msg = 0;
                while (true) {
                    emitter.emit("打招呼", "你好:" + msg);
                    msg++;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }).start();

        ArgsCallback hello3Callback = new ArgsCallback() {
            @Override
            public void invoke(Object[] args) {
                System.out.println("收到问候语3:" + Arrays.toString(args));
            }
        };

        emitter.on("打招呼", new ArgsCallback() {
            @Override
            public void invoke(Object[] args) {
                System.out.println("收到问候语1:" + Arrays.toString(args));
            }
        }).on("打招呼", new ArgsCallback() {
            @Override
            public void invoke(Object[] args) {
                System.out.println("收到问候语2:" + Arrays.toString(args));
            }
        }).on("打招呼", hello3Callback);
//        emitter.remove("打招呼", hello3Callback);
//        emitter.remove("打招呼");

    }

同步/异步 区别测试

public static void main(String[] args) {

        EventEmitter emitter = new EventEmitter();

        final int[] msg = {0};

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("触发前 消息msg是:" + msg[0]);
                    emitter.emit("交朋友", msg[0]);
                    System.out.println("触发后 消息msg是:" + msg[0]);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }).start();

        emitter.on("交朋友", new ArgsCallback() {
            @Override
            public void invoke(Object[] args) {
                msg[0] = (int) args[0] + 10;
                System.out.println("交到新朋友:" + msg[0]);
            }
        });

    }

异步执行

同步执行

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值