项目中遇到的多线程问题

供个人记录用。

一、问题描述

        客户端A通过MQTT协议向客户端B发送一条消息,客户端B需要根据消息的topic定位到金蝶云苍穹系统中的一个单据页面,并在页面中添加消息携带的message。

        按照以往设计插件的经验,只需要使用BusinessDataServiceHelper类就可以成功定位到单据页面。但是与注册插件不同的是,插件是由前端事件触发,从前端进入后端再由后端来对前端页面进行修改;而本问题中需要直接从后端来定位到前端页面并进行修改。所以就存在问题:无法从后端直接定位到前端单据页面

二、问题原因

        涉及了多线程问题,个人理解是前端页面的构建属于一个线程,MQTT协议的部分属于另一个线程,在执行MQTT协议的部分时,页面构建线程会被撤销,从而页面实体也就不存在了,所以是无法定位到单据页面的。

        要解决这一问题需要构建一个线程池,使得MQTT协议工作时,页面构建线程不会被撤销,然后在定位单据页面之前切换请求上下文(切换线程)。

(对线程的理解不太对,后续有更深刻了解后再做修改)

三、线程池概念介绍

1、线程池的作用

        线程池是一个暂存线程的存储空间,由一个线程队列与一个任务队列组成。线程队列保存着空闲线程,当线程运行结束,就加入线程队列等待下一个任务到来,而不是直接撤销。任务队列保存着等待执行的任务,若任务需要用到某个线程,则直接从线程队列中将其唤醒,而不需要重新创建。因此,线程池可以大大减少线程创建与销毁的开销

        此外,线程池还利于线程的管理、提高线程利用率和系统吞吐量。

2、线程池的参数

  • corePoolSize:线程池的核心线程数量,核心线程默认一直存活与线程池。
  • maxmumPoolSize:最大线程数。
  • keepAliveTime:临时线程的最大生存时间。
  • unit:规定keepAliveTime的时间单位。
  • workQueue:指定线程池的任务队列。
  • threadFactory:指定创建新线程的线程工厂。
  • rejectedExecutionHandler:规定线程池任务队列满了之后的处理策略。

3、线程池创建

苍穹环境下的创建:

参考:苍穹线程池的最佳实践

executeOnce执行一次
executeOnceIncludeRequestContext携带Request Context执行一次

newCachedThreadPool

创建可缓存线程池(返回ThreadPool接口)
newFixedThreadPool创建固定线程池(返回ThreadPool接口)
newCachedExecutorService创建可缓存线程池(返回jdk的ExecutorService接口)
newExecutorService

创建固定线程池(返回jdk的ExecutorService接口)

四、解决代码

        切换上下文的作用是切换数据源,让程序能从正确的数据源中定位到单据页面。

//创建executeOnce类型的线程池,此类线程池将会执行一次runnable的方法后销毁
//()->是Lambda表达式的写法,将函数作为方法的参数
ThreadPools.executeOnce("MQTT-TEST",()->{
    //MQTT相关动作
    *******
    *******
    // 配置请求上下文
    RequestContext rc = RequestContext.create(true);
    rc.setUserAgent("UserAgent");
    rc.setClient("Client");  //设置客户端
    rc.setTraceId(TraceId);
    rc.setTenantId("TenantId");
    rc.setAccountId("AccountId");
    rc.setUserId("UserId");
    rc.setLang(Lang.defaultLang());
    rc.setGlobalSessionId(SessionIdUtils.newSessionId());
    //切换上下文
    RequestContextThreadBinder.bind(rc);

    //定位单据页面    
    ******        
});

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值