perf[runnable]: 使用Runnable函数式编程接口

This commit is contained in:
godotg
2022-07-28 21:47:33 +08:00
parent a637db260a
commit c4cdf272eb
42 changed files with 105 additions and 142 deletions
@@ -29,7 +29,7 @@ import org.springframework.core.Ordered;
import java.util.concurrent.ExecutorService;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
* <p>
* 在EventRegisterProcessor 中完成扫描
@@ -59,9 +59,9 @@ public abstract class EventBus {
}
public static class EventThreadFactory implements ThreadFactory {
private int poolNumber;
private AtomicInteger threadNumber = new AtomicInteger(1);
private ThreadGroup group;
private final int poolNumber;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final ThreadGroup group;
public EventThreadFactory(int poolNumber) {
var s = System.getSecurityManager();
@@ -111,7 +111,7 @@ public abstract class EventBus {
executors[Math.abs(event.threadId() % EXECUTORS_SIZE)].execute(() -> doSubmit(event, list));
}
public static void asyncExecute(SafeRunnable runnable) {
public static void asyncExecute(Runnable runnable) {
execute(RandomUtils.randomInt(EXECUTORS_SIZE), runnable);
}
@@ -121,8 +121,8 @@ public abstract class EventBus {
* @param hashcode
* @return
*/
public static void execute(int hashcode, SafeRunnable runnable) {
executors[Math.abs(hashcode % EXECUTORS_SIZE)].execute(runnable);
public static void execute(int hashcode, Runnable runnable) {
executors[Math.abs(hashcode % EXECUTORS_SIZE)].execute(SafeRunnable.valueOf(runnable));
}
/**
@@ -18,7 +18,7 @@ import java.lang.annotation.*;
/**
* 接收事件的注解
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
@@ -21,7 +21,7 @@ import org.springframework.context.event.ApplicationContextEvent;
* <p>
* 启动顺序为:AppStartBeforeEvent -> AppStartEvent -> AppStartAfterEvent
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class AppStartAfterEvent extends ApplicationContextEvent {
@@ -21,7 +21,7 @@ import org.springframework.context.event.ApplicationContextEvent;
* <p>
* 启动顺序为:AppStartBeforeEvent -> AppStartEvent -> AppStartAfterEvent
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class AppStartBeforeEvent extends ApplicationContextEvent {
@@ -21,7 +21,7 @@ import org.springframework.context.event.ApplicationContextEvent;
* <p>
* 启动顺序为:AppStartBeforeEvent -> AppStartEvent -> AppStartAfterEvent
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class AppStartEvent extends ApplicationContextEvent {
@@ -16,7 +16,7 @@ package com.zfoo.event.model.event;
import com.zfoo.util.math.RandomUtils;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public interface IEvent {
@@ -25,7 +25,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public abstract class EnhanceUtils {
@@ -21,7 +21,7 @@ import java.lang.reflect.Method;
/**
* 动态代理被EventReceiver注解标注的方法,为了避免反射最终会用javassist字节码增强的方法去代理EventReceiverDefinition
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class EventReceiverDefinition implements IEventReceiver {
@@ -16,7 +16,7 @@ package com.zfoo.event.model.vo;
import com.zfoo.event.model.event.IEvent;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public interface IEventReceiver {
@@ -22,7 +22,7 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class EventDefinitionParser implements BeanDefinitionParser {
@@ -32,7 +32,7 @@ import java.lang.reflect.Modifier;
* 这是一个后置处理器,在boot项目中注册EventContext时,会import导入EventRegisterProcessor这个组件,这是一个后置处理器,
* 断点发现 在AbstractAutowireCapableBeanFactory或调用getBeanPostProcessors,这样子每一个后置处理器都会走postProcessAfterInitialization这个方法
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class EventRegisterProcessor implements BeanPostProcessor {
@@ -16,7 +16,7 @@ package com.zfoo.event.schema;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class NamespaceHandler extends NamespaceHandlerSupport {
@@ -20,7 +20,7 @@ import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
@Ignore
@@ -19,7 +19,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
@Component
@@ -19,7 +19,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
@Component
@@ -16,7 +16,7 @@ package com.zfoo.event;
import com.zfoo.event.model.event.IEvent;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class MyNoticeEvent implements IEvent {
@@ -29,7 +29,6 @@ import com.zfoo.protocol.util.IOUtils;
import com.zfoo.protocol.util.JsonUtils;
import com.zfoo.protocol.util.StringUtils;
import com.zfoo.scheduler.manager.SchedulerBus;
import com.zfoo.util.SafeRunnable;
import com.zfoo.util.ThreadUtils;
import com.zfoo.util.net.HostAndPort;
import io.netty.util.concurrent.FastThreadLocalThread;
@@ -361,12 +360,7 @@ public class ZookeeperRegistry implements IRegistry {
} catch (Exception e) {
//
logger.error("zookeeper初始化失败,等待[{}]秒,重新初始化", RETRY_SECONDS, e);
SchedulerBus.schedule(new SafeRunnable() {
@Override
public void doRun() {
initZookeeper();
}
}, RETRY_SECONDS, TimeUnit.SECONDS);
SchedulerBus.schedule(() -> initZookeeper(), RETRY_SECONDS, TimeUnit.SECONDS);
}
});
}
@@ -522,12 +516,7 @@ public class ZookeeperRegistry implements IRegistry {
}
if (recheckFlag) {
SchedulerBus.schedule(new SafeRunnable() {
@Override
public void doRun() {
checkConsumer();
}
}, RETRY_SECONDS, TimeUnit.SECONDS);
SchedulerBus.schedule(() -> checkConsumer(), RETRY_SECONDS, TimeUnit.SECONDS);
}
}
@@ -73,9 +73,9 @@ public final class TaskBus {
}
public static class TaskThreadFactory implements ThreadFactory {
private int poolNumber;
private AtomicInteger threadNumber = new AtomicInteger(1);
private ThreadGroup group;
private final int poolNumber;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final ThreadGroup group;
public TaskThreadFactory(int poolNumber) {
var s = System.getSecurityManager();
@@ -124,8 +124,8 @@ public final class TaskBus {
return Math.abs(executorConsistentHash % EXECUTOR_SIZE);
}
public static void execute(int executorConsistentHash, SafeRunnable runnable) {
executors[executorIndex(executorConsistentHash)].execute(runnable);
public static void execute(int executorConsistentHash, Runnable runnable) {
executors[executorIndex(executorConsistentHash)].execute(SafeRunnable.valueOf(runnable));
}
// 在taskeventscheduler线程执行的异步请求,请求成功过后依然在相同的线程执行回调任务
@@ -20,7 +20,6 @@ import com.zfoo.event.manager.EventBus;
import com.zfoo.protocol.collection.CollectionUtils;
import com.zfoo.protocol.model.Pair;
import com.zfoo.scheduler.manager.SchedulerBus;
import com.zfoo.util.SafeRunnable;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -94,31 +93,25 @@ public class SimpleCache<K, V> {
});
SchedulerBus.scheduleAtFixedRate(new SafeRunnable() {
@Override
public void doRun() {
// 不在任务调度线程中执行耗时任务,因为任务调度线程只有一个线程池
EventBus.asyncExecute(new SafeRunnable() {
@Override
public void doRun() {
var list = new ArrayList<K>();
while (!linkedQueue.isEmpty()) {
var key = linkedQueue.poll();
list.add(key);
if (list.size() >= BATCH_RELOAD_SIZE) {
var result = batchLoadCallback.apply(list);
result.forEach(it -> cache.put(it.getKey(), it.getValue()));
list.clear();
}
}
if (CollectionUtils.isNotEmpty(list)) {
var result = batchLoadCallback.apply(list);
result.forEach(it -> cache.put(it.getKey(), it.getValue()));
}
SchedulerBus.scheduleAtFixedRate(() -> {
// 不在任务调度线程中执行耗时任务,因为任务调度线程只有一个线程池
EventBus.asyncExecute(() -> {
var list = new ArrayList<K>();
while (!linkedQueue.isEmpty()) {
var key = linkedQueue.poll();
list.add(key);
if (list.size() >= BATCH_RELOAD_SIZE) {
var result = batchLoadCallback.apply(list);
result.forEach(it -> cache.put(it.getKey(), it.getValue()));
list.clear();
}
});
}
}
if (CollectionUtils.isNotEmpty(list)) {
var result = batchLoadCallback.apply(list);
result.forEach(it -> cache.put(it.getKey(), it.getValue()));
}
});
}, refreshDuration, TimeUnit.MILLISECONDS);
@@ -15,7 +15,6 @@ package com.zfoo.net.util;
import com.zfoo.event.manager.EventBus;
import com.zfoo.scheduler.util.TimeUtils;
import com.zfoo.util.SafeRunnable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -62,12 +61,7 @@ public class SingleCache<V> {
try {
if (now > refreshTime) {
refreshTime = now + refreshDuration;
EventBus.asyncExecute(new SafeRunnable() {
@Override
public void doRun() {
cache = supplier.get();
}
});
EventBus.asyncExecute(() -> cache = supplier.get());
}
} finally {
lock.unlock();
@@ -15,7 +15,6 @@ package com.zfoo.net.router;
import com.zfoo.event.manager.EventBus;
import com.zfoo.net.router.route.SignalBridge;
import com.zfoo.scheduler.util.TimeUtils;
import com.zfoo.util.SafeRunnable;
import com.zfoo.util.ThreadUtils;
import org.junit.Ignore;
import org.junit.Test;
@@ -55,9 +54,9 @@ public class SignalBridgeTest {
var countDownLatch = new CountDownLatch(executorSize);
for (var i = 0; i < executorSize; i++) {
EventBus.execute(i, new SafeRunnable() {
EventBus.execute(i, new Runnable() {
@Override
public void doRun() {
public void run() {
addAndRemoveArray();
countDownLatch.countDown();
}
@@ -73,9 +72,9 @@ public class SignalBridgeTest {
var countDownLatch = new CountDownLatch(executorSize);
for (int i = 0; i < executorSize; i++) {
EventBus.execute(i, new SafeRunnable() {
EventBus.execute(i, new Runnable() {
@Override
public void doRun() {
public void run() {
addAndRemoveMap();
countDownLatch.countDown();
}
@@ -20,7 +20,6 @@ import com.zfoo.orm.model.vo.EntityDef;
import com.zfoo.protocol.exception.ExceptionUtils;
import com.zfoo.scheduler.manager.SchedulerBus;
import com.zfoo.scheduler.util.TimeUtils;
import com.zfoo.util.SafeRunnable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.support.CronExpression;
@@ -43,7 +42,7 @@ public class CronOrmPersister extends AbstractOrmPersister {
/**
* cron表达式
*/
private CronExpression cronExpression;
private final CronExpression cronExpression;
public CronOrmPersister(EntityDef entityDef, EntityCaches<?, ?> entityCaches) {
@@ -75,18 +74,12 @@ public class CronOrmPersister extends AbstractOrmPersister {
}
if (!OrmContext.isStop()) {
SchedulerBus.schedule(new SafeRunnable() {
@Override
public void doRun() {
if (!OrmContext.isStop()) {
EventBus.execute(entityDef.getClazz().hashCode(), new SafeRunnable() {
@Override
public void doRun() {
entityCaches.persistAll();
schedulePersist();
}
});
}
SchedulerBus.schedule(() -> {
if (!OrmContext.isStop()) {
EventBus.execute(entityDef.getClazz().hashCode(), () -> {
entityCaches.persistAll();
schedulePersist();
});
}
}, delay, TimeUnit.MILLISECONDS);
}
@@ -19,7 +19,6 @@ import com.zfoo.orm.model.cache.EntityCaches;
import com.zfoo.orm.model.vo.EntityDef;
import com.zfoo.protocol.util.StringUtils;
import com.zfoo.scheduler.manager.SchedulerBus;
import com.zfoo.util.SafeRunnable;
import java.util.concurrent.TimeUnit;
@@ -32,7 +31,7 @@ public class TimeOrmPersister extends AbstractOrmPersister {
/**
* 执行的频率
*/
private long rate;
private final long rate;
public TimeOrmPersister(EntityDef entityDef, EntityCaches<?, ?> entityCaches) {
super(entityDef, entityCaches);
@@ -44,17 +43,9 @@ public class TimeOrmPersister extends AbstractOrmPersister {
@Override
public void start() {
SchedulerBus.scheduleAtFixedRate(new SafeRunnable() {
@Override
public void doRun() {
if (!OrmContext.isStop()) {
EventBus.execute(entityDef.getClazz().hashCode(), new SafeRunnable() {
@Override
public void doRun() {
entityCaches.persistAll();
}
});
}
SchedulerBus.scheduleAtFixedRate(() -> {
if (!OrmContext.isStop()) {
EventBus.execute(entityDef.getClazz().hashCode(), () -> entityCaches.persistAll());
}
}, rate, TimeUnit.MILLISECONDS);
}
@@ -15,7 +15,6 @@ package com.zfoo.orm.lpmap;
import com.zfoo.event.manager.EventBus;
import com.zfoo.orm.lpmap.model.MyPacket;
import com.zfoo.protocol.ProtocolManager;
import com.zfoo.util.SafeRunnable;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
@@ -42,9 +41,9 @@ public class ConcurrentFileChannelMapTest {
var countdown = new CountDownLatch(EventBus.EXECUTORS_SIZE);
for (int i = 0; i < EventBus.EXECUTORS_SIZE; i++) {
EventBus.asyncExecute(new SafeRunnable() {
EventBus.asyncExecute(new Runnable() {
@Override
public void doRun() {
public void run() {
var key = atomicInt.getAndIncrement();
while (key < count) {
var myPacket = MyPacket.valueOf(key, String.valueOf(key));
@@ -15,7 +15,6 @@ package com.zfoo.orm.lpmap;
import com.zfoo.event.manager.EventBus;
import com.zfoo.orm.lpmap.model.MyPacket;
import com.zfoo.protocol.ProtocolManager;
import com.zfoo.util.SafeRunnable;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
@@ -59,17 +58,14 @@ public class ConcurrentHeapMapTest {
var countdown = new CountDownLatch(EventBus.EXECUTORS_SIZE);
for (int i = 0; i < EventBus.EXECUTORS_SIZE; i++) {
EventBus.asyncExecute(new SafeRunnable() {
@Override
public void doRun() {
var key = atomicInt.getAndIncrement();
while (key < count) {
var myPacket = MyPacket.valueOf(key, String.valueOf(key));
map.put(key, myPacket);
key = atomicInt.getAndIncrement();
}
countdown.countDown();
EventBus.asyncExecute(() -> {
var key = atomicInt.getAndIncrement();
while (key < count) {
var myPacket = MyPacket.valueOf(key, String.valueOf(key));
map.put(key, myPacket);
key = atomicInt.getAndIncrement();
}
countdown.countDown();
});
}
countdown.await();
@@ -34,7 +34,7 @@ import java.lang.reflect.Modifier;
import java.util.concurrent.ScheduledExecutorService;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class SchedulerContext implements ApplicationListener<ApplicationContextEvent>, Ordered {
@@ -72,7 +72,7 @@ public abstract class SchedulerBus {
public static class SchedulerThreadFactory implements ThreadFactory {
private int poolNumber;
private final int poolNumber;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final ThreadGroup group;
@@ -166,24 +166,24 @@ public abstract class SchedulerBus {
/**
* 不断执行的周期循环任务
*/
public static void scheduleAtFixedRate(SafeRunnable runnable, long period, TimeUnit unit) {
public static void scheduleAtFixedRate(Runnable runnable, long period, TimeUnit unit) {
if (SchedulerContext.isStop()) {
return;
}
executor.scheduleAtFixedRate(runnable, 0, period, unit);
executor.scheduleAtFixedRate(SafeRunnable.valueOf(runnable), 0, period, unit);
}
/**
* 固定延迟执行的任务
*/
public static void schedule(SafeRunnable runnable, long delay, TimeUnit unit) {
public static void schedule(Runnable runnable, long delay, TimeUnit unit) {
if (SchedulerContext.isStop()) {
return;
}
executor.schedule(runnable, delay, unit);
executor.schedule(SafeRunnable.valueOf(runnable), delay, unit);
}
/**
@@ -18,12 +18,12 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class StopWatch {
private long startTime = TimeUtils.currentTimeMillis();
private final long startTime = TimeUtils.currentTimeMillis();
public long cost() {
return TimeUtils.currentTimeMillis() - startTime;
@@ -16,7 +16,7 @@ package com.zfoo.scheduler.model.anno;
import java.lang.annotation.*;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
@Documented
@@ -24,7 +24,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public abstract class EnhanceUtils {
@@ -14,7 +14,7 @@
package com.zfoo.scheduler.model.vo;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public interface IScheduler {
@@ -20,7 +20,7 @@ import java.lang.reflect.Method;
/**
* 动态代理被Scheduler注解标注的方法,为了避免反射最终会用javassist字节码增强的方法去代理ReflectScheduler
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class ReflectScheduler implements IScheduler {
@@ -14,7 +14,7 @@
package com.zfoo.scheduler.model.vo;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class RunnableScheduler implements IScheduler {
@@ -23,7 +23,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class SchedulerDefinition {
@@ -16,7 +16,7 @@ package com.zfoo.scheduler.schema;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class NamespaceHandler extends NamespaceHandlerSupport {
@@ -31,7 +31,7 @@ import org.w3c.dom.Element;
* 从而可以得出结论:在基于zfoo的SpringBoot工程中,由于压根不解析xml对象,注册bean也是通过@Configuration配置类注册bean的,
* 因此这些实现BeanDefinitionParser接口的parse方法是都不会执行的。
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class SchedulerDefinitionParser implements BeanDefinitionParser {
@@ -26,7 +26,7 @@ import java.util.Date;
import java.util.TimeZone;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public abstract class TimeUtils {
@@ -22,7 +22,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
* cron译为克龙代表100万年是英文单词中最大的时间单位
* google译为古戈尔代表10的100次方足够穷尽宇宙万物
*
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
@@ -19,7 +19,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
@Component
@@ -25,7 +25,7 @@ import java.time.temporal.TemporalAdjusters;
import java.util.Date;
/**
* @author jaysunxiao
* @author godotg
* @version 3.0
*/
public class TimeUtilsTest {
@@ -7,14 +7,25 @@ import org.slf4j.LoggerFactory;
* @author godotg
* @version 3.0
*/
public abstract class SafeRunnable implements Runnable {
public class SafeRunnable implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(SafeRunnable.class);
private Runnable runnable;
private SafeRunnable() {
}
public static SafeRunnable valueOf(Runnable runnable) {
var run = new SafeRunnable();
run.runnable = runnable;
return run;
}
@Override
public void run() {
try {
doRun();
runnable.run();
} catch (Exception e) {
logger.error("未知exception异常", e);
} catch (Throwable t) {
@@ -22,6 +33,4 @@ public abstract class SafeRunnable implements Runnable {
}
}
public abstract void doRun();
}