设计模式-插件模式

在项目中自己提炼出了插件模式的一种设计方案,场景如下:
比如当某个模块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即可

在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_令狐大侠_

觉的文章对你有用,鼓励一下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值