多线程处理服务实例

总结一下,实际用到的多线程处理实例。

假设有这么个场景:有一场考试,考生们都是用电脑答题,然后打完了就会点击保存,系统自动批阅。

分析:

1.肯定是异步批阅

2.有定时任务定期拉取学生的试卷

3.定时任务处理的数据不能冲突

4.根据试卷的种类可能要分多种服务

5.根据试卷的种类数量可能需要拟定并发数,保证效率

6.支持数据异常处理,防止处理过程中出现以外

7.增加日志监控体系

实现:

1.配置一个监听器,心跳机制,主线程永不销毁

2.工厂模式实现服务调度,根据种类区分N个批阅服务

3.每个服务采用单独线程池管理,配置并发数

4.通过代码锁和数据库锁来保证数据的唯一性

5.用线程本地变量记录相关日志信息

代码:

监听器配置:

web.xml配置

<listener-class>XXXX.XXXX.MainListener</listener-class>

主线程配置:

//自定义主线程thread
Thread mainThread = new MainThread(); // MainThread需要继承Thread

mainThread .start();


//MainThread中的run方法
    public void run() {
        while (true) {
             //创建对应线程池A
             //创建对应线程池B

             sleep(time)  //多久运行一次
        }
     }        

 

获取和创建线程池

    private static ConcurrentHashMap<String,ThreadPoolExecutor>  excutor = new ConcurrentHashMap<>();
    
    //xcbs代表线程类型
    public static synchronized ThreadPoolExecutor getExecutor(String xcbs) {
     //判断是否已经创建
        ThreadPoolExecutor exc = excutor.get(xcbs);

        if(isNull(exc)) {
                final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(queueThread);
                exc = new ThreadPoolExecutor(5,5, 0L, TimeUnit.MILLISECONDS, queue, new ThreadPoolExecutor.CallerRunsPolicy());
                excutor.put(xcbs, exc);
                return exc;
            }
        }
        return exc;
    }

 

日志监控处理:

//初始化日志对象
//final ZxrzbDTO zxrzDTO = new ZxrzbDTO();

//初始化线程日志对象
  private static ThreadLocal<ZxrzbDTO > logManger = new ThreadLocal<ZxrzbDTO >();

//get方法
public static ZxrzbDTO get() {
        ZxrzbDTO log = (ZxrzbDTO ) logManger.get();
        if (isNull(log)) {
            log = new ZxrzbDTO();
            logManger.set(log);
        }
        return log;
    }

 

写的有点草率,但是就是一个异步处理的逻辑,监听器+工厂模式+线程池+日志监控,有需要的可以交流

 

 

 

 

 

 

 

 

 

//创建对应线程池B
posted @ 2022-01-21 16:09  哦咯哦咯  阅读(116)  评论(0)    收藏  举报