一、项目环境
- spring、tomcat 项目、工作流
二、需求背景
- 做一个公司内部资产盘点,给员工发送任务待办消息,同时要发送3000待办任务。
三、遇到的问题
- 如果同时发送3000个待办,响应时间太长,等待时间太长。
四、解决方案
- 采用多线程解决方案
- 定时任务、消息队列发送
五、实现方案
1、多线程方案
- 1.1、线程的创建
-
public class WaitThread implements Runnable { private List list = Collections.synchronizedList(new ArrayList()); private String name; private CountDownLatch countDownLatch; GjjPO po = new GjjPO(); public WaitThread(List list1, String name, CountDownLatch latch) { this.list = list1; this.name = name; this.countDownLatch = latch; } @Override public void run() { try { for (int i = 0; i < list.size(); i++) { System.out.println("线程" + name + "正在处理" + list.get(i)); String id = list.get(i).toString(); //业务处理调用 createTask(id); System.out.println("线程" + name + "处理完成" + list.get(i)); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); }finally { if (countDownLatch != null){ countDownLatch.countDown(); } } } }
-
1.2、线程调用
-
List idList = Collections.synchronizedList(new ArrayList()); //多线程实现待办发送 int threadNum = 10; int length = query.length; if (length != 0) { if (length < threadNum) { threadNum = length; } if (length > 500) { threadNum = 50; } if (length > 1000) { threadNum = 100; } int perSize = 0; if (length % threadNum != 0) { perSize = length / threadNum + 1; } else { perSize = length / threadNum; } ExecutorService executorService = Executors.newFixedThreadPool(threadNum); CountDownLatch countDownLatch = new CountDownLatch(threadNum); for (int i = 0; i < threadNum; i++) { List newList = Collections.synchronizedList(new ArrayList()); try{ if((i + 1) * perSize > length){ newList = idList.subList(i * perSize, length); }else { newList = idList.subList(i * perSize, (i + 1) * perSize); } }catch (Exception e){ System.out.println("异常数据:"+e); } WaitThread waitThread = new WaitThread(newList, "线程" + i, countDownLatch); Thread t1 = new Thread(waitThread); executorService.submit(t1); } countDownLatch.await(); executorService.shutdown(); } }
这里说明一下,我为什么这么创建线程数量:
-
功能使用过程中,发送待办任务,没有固定数量,所以我在创建线程数量时,依据数量创建线程数。
六、实际上线遇到的问题
1、功能执行过程中运行程序报错,但是线程已经创建成功,优化程序后继续执行该功能,这次所有待办成功发送,线程成功执行。
但是,这时候第一次发起的线程,项目重新启动并没有停止,等项目内存释放以后,线程开始运行,最终导致待办任务重复生成。
最后,我放弃多线程,采用了定时任务消息队列发送。
七、征集意见
1、为什么项目重启,线程没有结束?
2、对于我的业务会有事务提交,会对表新增数据,建议使用多线程吗?