玩转设计模式:了解插件模式的奥秘
最编程
2024-08-06 13:57:59
...
在项目中自己提炼出了插件模式的一种设计方案,场景如下:
比如当某个模块a依赖n多个线程,模块a有个控制开关,可以一起启动n个线程或者停止n个线程,并且还可以指定线程名进行重启,如何有效的去管理呢,直接上代码
1.SmallPlug 插件接口文件
/**
* 小插件初始化,停止,运行
*/
public interface SmallPlug {
/**
* 初始化
*/
void initPlus();
/**
* 启动插件
*/
void startPlus();
/**
* 停止插件
*/
void stopPlus();
}
2.插件线程基础类:
/**
* 插件线程基础类
*/
public class BaseThreadPlus implements SmallPlug {
public String getThreadName() {
return threadName;
}
public Thread getSelfThread() {
return selfThread;
}
public AbstractRunable getSelfRunable() {
return selfRunable;
}
private String threadName="";
private Thread selfThread=null;
private AbstractRunable selfRunable=null;
public BaseThreadPlus(String threadName, AbstractRunable runnable){
this.threadName=threadName+"-"+DateUtil.now();
this.selfRunable=runnable;
}
@Override
public void initPlus() {
}
@Override
public void startPlus() {
Thread t = new Thread(selfRunable);
t.setName(threadName);
selfThread=t;
selfRunable.run=true;
t.start();
}
@Override
public void stopPlus() {
selfRunable.run=false;
selfThread.interrupt();
}
//无构造函数初始化线程
public static BaseThreadPlus loadBaseThreadPlus(String threadName, Class classs){
AbstractRunable runableObj= (AbstractRunable) ReflectUtil.newInstance(classs);
BaseThreadPlus plus= ReflectUtil.newInstance(BaseThreadPlus.class,threadName,runableObj);
return plus;
}
//有构造函数初始化线程
public static BaseThreadPlus loadBaseThreadPlus(String threadName, Class classs,Object... param){
AbstractRunable runableObj= (AbstractRunable) ReflectUtil.newInstance(classs,param);
BaseThreadPlus plus= ReflectUtil.newInstance(BaseThreadPlus.class,threadName,runableObj);
return plus;
}
}
3.抽象任务执行类
public abstract class AbstractRunable implements Runnable {
public volatile boolean run=false;
@Override
public abstract void run();
}
4.具体的业务执行者A,B类
@Slf4j
public class WorkDemoARunable extends AbstractRunable {
@Override
public void run() {
while (this.run){
try {
try {
log.info("执行后台复杂任务A");
Thread.sleep(1000*30);
} catch (InterruptedException e) {
log.error("WorkDemoARunable 被中断",e);
}
} catch (Exception e) {
log.error("WorkDemoARunable 处理异常:",e);
}catch (Throwable e){
log.error("WorkDemoARunable 崩溃:",e);
}
}
}
}
@Slf4j
public class WorkDemoBRunable extends AbstractRunable {
@Override
public void run() {
while (this.run){
try {
try {
log.info("执行后台复杂任务B");
Thread.sleep(1000*30);
} catch (InterruptedException e) {
log.error("WorkDemoBRunable 被中断",e);
}
} catch (Exception e) {
log.error("WorkDemoBRunable 处理异常:",e);
}catch (Throwable e){
log.error("WorkDemoBRunable 崩溃:",e);
}
}
}
}
5.模块的引导程序
/**
* 调度功能模块A
*/
@Service
@Slf4j
public class DispatchBoot implements SmallPlug{
private Map<String,BaseThreadPlus> plugThreadMap=new LinkedHashMap<>();
//调度引导程序状态
private volatile boolean isRun= false;
@Autowired
private StationService stationService;
@Override
public synchronized void initPlus() {
if (MapUtil.isNotEmpty(plugThreadMap)){
stopPlus();
}
//加载插件线程1
BaseThreadPlus plusA= BaseThreadPlus.loadBaseThreadPlus(WorkDemoARunable.class.getSimpleName(),
WorkDemoARunable.class);
plugThreadMap.put(WorkDemoARunable.class.getSimpleName(),plusA);
//加载插件线程2
BaseThreadPlus plusB= BaseThreadPlus.loadBaseThreadPlus(WorkDemoBRunable.class.getSimpleName(),
WorkDemoBRunable.class);
plugThreadMap.put(WorkDemoBRunable.class.getSimpleName(),plusB);
log.info("初始化完成插件线程");
}
@Override
public synchronized void startPlus() {
if (isRun){
log.info("采集插件线程已经在运行,必选先停止其运行");
return;
}
plugThreadMap.forEach((k,v)->{
v.startPlus();
});
isRun=true;
log.info("已启动所有的采集插件线程");
}
//停止当前所有插件线程
@Override
public synchronized void stopPlus() {
plugThreadMap.forEach((k,v)->{
v.stopPlus();
});
isRun=false;
plugThreadMap.clear();
log.info("停止完成采集插件线程");
}
/**
* 根据key来搜索线程
* @param plusKey
* @return
*/
public BaseThreadPlus getPlusByKey(String plusKey){
return plugThreadMap.get(plusKey);
}
/**
* 搜索插件线程
* @param namePrefix
* @return
*/
private List<BaseThreadPlus> findThreadPlus(String namePrefix){
List<BaseThreadPlus> list=new ArrayList<>();
for (Map.Entry<String, BaseThreadPlus> entry : plugThreadMap.entrySet()) {
if (entry.getKey().startsWith(namePrefix)){
list.add(entry.getValue());
}
}
return list;
}
/**
* 中断插件线程
* @param namePrefix
*/
public void interruptPlus(String namePrefix){
List<BaseThreadPlus> list=findThreadPlus(namePrefix);
if (CollUtil.isNotEmpty(list)){
list.forEach(e->{
e.getSelfThread().interrupt();
});
}
};
public static void main(String[] args) {
//模块A自己也是个插件,可以集成到业务模块中
DispatchBoot boot=new DispatchBoot();
boot.initPlus();
boot.startPlus();
}
}
6.执行DispatchBoot 的main方法,后输出如下,是不是对线程管理更好了,DispatchBoot 还提供了线程查找,中断等常用功能,DispatchBoot 其实自己也是个插件,可以插入到其他业务中,其他的业务只需要调用initPlus,startPlus,stopPlus即可
上一篇: 深入理解单例设计模式:懒汉式与饿汉式的详解及代码示例
下一篇: Vue项目中的装饰器模式简介
推荐阅读
-
入门JavaScript设计模式:了解设计模式的基本概念
-
玩转JavaScript进阶系列(43):揭秘状态模式的奥秘
-
玩转JS版设计模式(11):揭秘JavaScript中的装饰器模式
-
JavaScript必知的设计模式,你了解哪些JS设计模式呢?
-
插件模式详解:设计模式中的重要一环
-
玩转设计模式:了解插件模式的奥秘
-
玩转 JavaScript 设计模式:探索超级玛丽中的状态模式
-
探索设计模式的魅力:了解Object Pool(对象池)
-
汽车后面的字母是什么意思?-增压发动机 类型一:TSI 大众的TSI在国内外有着不一样的意思,国外的意思是Twincharger Stratified ion,指双增压(涡轮和机械增压)分层喷射技术。而国内的意思,T代表涡轮增压,Si代表燃油直喷,而不是T与FSI的简称,并没有燃油分层喷射技术,因为国内燃油质量一般,达不到分层喷射的要求。 在国内,我们经常会看到不同的TSI标志。有全红的、有就“SI”是红的、还有只有“I”是红的。但大家别误会他们技术不一样,这只是为了区分不同的排量而已。例如:2.0排量和1.8排量为“SI”是红色的,而2.0TSI车型中的高配车型或者高端车型则使用全红的标识,那么1.4排量的当然只能是只有“I”是红色的了。 类型二:TFSI TFSI发动机也是涡轮燃油直喷发动机它可以说是FSI发动机和涡轮增压器的结合。即涡轮增压(Turbocharger)+FSI。它的T和TSI中的T一样,表示采用涡轮增压技术,后面的FSI即燃油分层喷射发动机(Fuel Stratified ion),S表示“分层次的”。TFSI发动机既分层喷射,又有涡轮增压,是TSI发动机的升级版。 类型三:TDI TDI是英文Turbo Direct ion的缩写,意为涡轮增压直接喷射柴油发动机。 为了解决SDI(自然吸气式柴油发动机)的先天不足,人们在柴油机上加装了涡轮增压装置,使得进气压力大大增加,压缩比一般都到10以上,这样就可以在转速很低的情况下达到很大的扭矩,而且由于燃烧更加充分,排放物中的有害颗粒含量也大大降低。TDI技术使燃油经由一个高压喷射器直接喷射入气缸,因为活塞顶地造型是一个凹陷式的碗状设计,燃油会在气缸内形成一股螺旋状的混合气。 自然吸气发动机类型一:CGI/CDI 发动机CGI技术是一种奔驰公司开发的缸内直喷技术。供油动作已完全独立于进门与活塞系统之外,ECU也因而拥有更多的主导权。超乎传统喷射理论的稀薄燃烧与更多元的混合比便得以实现。在稳定行进或低负载状态下,采用缸内直喷设计的发动机得以进入Ultra lean(精实)模式。 在此设定下,发动机于进气行程时只能吸进空气,至于喷油嘴则在压缩行程才供给燃料,以达到节约的效果。根据实际测试,其最高能达到1:65的油、气比例,除了节能表现相当惊人,整体动力曲线也能够维持相当高的平顺度。而CDI则为该技术的柴油版本。类型二:VVT/CVVT/VVT-I/MIVEC/VTEC/i-VTEC 发动机可变气门正时技术(VVT,Variable Valve Timing)原理是根据发动机的运行情况,调整进气(排气)的量,和气门开合时间、角度,使进入的空气量达到最佳,提高燃烧效率。优点是省油,功升比大而缺点是中段转速扭矩不足。 目前本田的VTEC、i-VTEC、;丰田的VVT-i;日产的CVVT;三菱的MIVEC;铃木的VVT;现代的VVT;起亚的CVVT;江淮的VVT;长城的VVT等也逐渐开始使用。总的说来其实就是一种技术,名字不同。 但部分车型仅具有可变气门技术而没有正时技术,虽然比一般发动机要省油,但依然赶不上带正时技术的发动机。绿色发动机 类型一:Hybrid
-
玩转Java编程:探索命令模式的奥秘