
com.sghd.common.event.EventBusImpl Maven / Gradle / Ivy
The newest version!
package com.sghd.common.event;
import java.lang.management.ManagementFactory;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.sghd.common.utils.thread.NamedThreadFactory;
/**
* 事件总线接口的实现类
*/
@Component
public class EventBusImpl implements EventBus, EventBusImplMBean {
private static final Logger logger = LoggerFactory.getLogger(EventBusImpl.class);
/** 注册的事件接收者 */
private ConcurrentHashMap>> receivers = new ConcurrentHashMap>>();
@Autowired(required = false)
@Qualifier("event_queue_size")
private Integer queueSize = 32768;
@Autowired(required = false)
@Qualifier("event_pool_size")
private Integer poolSize = 5;
@Autowired(required = false)
@Qualifier("event_pool_max_size")
private Integer poolMaxSize = 10;
@Autowired(required = false)
@Qualifier("event_pool_alive_time")
private Integer poolKeepAlive = 60;
@Autowired(required = false)
@Qualifier("event_pool_await_time")
private Integer poolAwaitTime = 60;
private ExecutorService pool;
/**
* 根据配置初始化
*/
@PostConstruct
protected void initialize() {
ThreadGroup threadGroup = new ThreadGroup("事件模块");
NamedThreadFactory threadFactory = new NamedThreadFactory(threadGroup, "事件处理");
pool = new ThreadPoolExecutor(poolSize, poolMaxSize, poolKeepAlive, TimeUnit.SECONDS,
new LinkedBlockingQueue(queueSize), threadFactory);
// 注册MBean
try {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.sghd.common:type=EventBusMBean");
mbs.registerMBean(this, name);
} catch (Exception e) {
logger.error("注册[common-event]的JMX管理接口失败", e);
}
}
/** 销毁方法 */
@PreDestroy
public void destory() {
shutdown();
}
/** 停止状态 */
private volatile boolean stop;
/**
* 关闭事件总线,阻塞方法会等待总线中的全部事件都发送完后再返回
*/
public void shutdown() {
if (isStop())
return;
stop = true;
ThreadPoolExecutor executor = ((ThreadPoolExecutor) pool);
for (;;) {
if (executor.getQueue().isEmpty()) {
break;
}
Thread.yield();
}
// 等待线程池关闭
pool.shutdown();
logger.error("开始关闭事件总线线程池");
try {
if (!pool.awaitTermination(poolAwaitTime, TimeUnit.SECONDS)) {
logger.error("无法在预计时间内完成事件总线线程池关闭,尝试强行关闭");
pool.shutdownNow();
if (!pool.awaitTermination(poolAwaitTime, TimeUnit.SECONDS)) {
logger.error("事件总线线程池无法完成关闭");
}
}
} catch (InterruptedException e) {
logger.error("事件总线线程池关闭时线程被打断,强制关闭事件总线线程池");
pool.shutdownNow();
}
}
/**
* 检查该事件总线是否已经停止服务
* @return
*/
public boolean isStop() {
return stop;
}
@Override
public void post(Event> event) {
if (event == null) {
throw new IllegalArgumentException("事件对象不能为空");
}
if (stop) {
throw new IllegalStateException("事件总线已经停止,不能再接收事件");
}
String name = event.getName();
if (!receivers.containsKey(name)) {
logger.warn("事件[{}]没有对应的接收器", name);
return;
}
for (Receiver> receiver : receivers.get(name)) {
Runnable runner = createRunner(receiver, event);
try {
pool.submit(runner);
} catch (RejectedExecutionException e) {
logger.error("事件线程池已满,请尽快调整配置参数");
onRejected(receiver, event);
}
}
}
@Override
public void register(String name, Receiver> receiver) {
if (name == null || receiver == null) {
throw new IllegalArgumentException("事件名和接收者均不能为空");
}
CopyOnWriteArraySet> set = receivers.get(name);
if (set == null) {
set = new CopyOnWriteArraySet<>();
CopyOnWriteArraySet> prev = receivers.putIfAbsent(name, set);
set = prev != null ? prev : set;
}
set.add(receiver);
}
@Override
public void unregister(String name, Receiver> receiver) {
if (name == null || receiver == null) {
throw new IllegalArgumentException("事件名和接收者均不能为空");
}
CopyOnWriteArraySet> set = receivers.get(name);
if (set != null) {
set.remove(receiver);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void syncPost(Event> event) {
String name = event.getName();
if (!receivers.containsKey(name)) {
logger.warn("事件'{}'没有对应的接收器", name);
return;
}
for (Receiver receiver : receivers.get(name)) {
try {
receiver.onEvent(event);
} catch (Exception e) {
logger.error("事件[" + event.getName() + "]处理时发生异常", e);
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void onRejected(Receiver receiver, Event event) {
try {
receiver.onEvent(event);
} catch (ClassCastException e) {
logger.error("事件[" + event.getName() + "]对象类型不符合接收器声明", e);
} catch (Throwable t) {
logger.error("事件[" + event.getName() + "]处理时发生异常", t);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private Runnable createRunner(final Receiver receiver, final Event event) {
return new Runnable() {
@Override
public void run() {
try {
receiver.onEvent(event);
} catch (ClassCastException e) {
logger.error("事件[" + event.getName() + "]对象类型不符合接收器[" + receiver.getClass() + "]声明", e);
} catch (Throwable t) {
logger.error("事件[" + event.getName() + "]处理器[" + receiver.getClass() + "]运行时发生异常", t);
}
}
};
}
// JMX管理接口的实现方法
@Override
public int getEventQueueSize() {
return ((ThreadPoolExecutor) pool).getQueue().size();
}
@Override
public int getPoolActiveCount() {
return ((ThreadPoolExecutor) pool).getActiveCount();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy