多线程处理服务实例
总结一下,实际用到的多线程处理实例。
假设有这么个场景:有一场考试,考生们都是用电脑答题,然后打完了就会点击保存,系统自动批阅。
分析:
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

浙公网安备 33010602011771号