背景:
项目中有一个疑难用户入库task,该task是全国范围共用的,事件单是湖北提出的,说是入库的数据出现了重复的,一开始就按照特殊省份对待定位,结果跑偏了
问题很简单,但是很难发现:现帖出问题代码
TaskEngine是线程池工具类,这里是异步调用入库接口,数据封装在inputObject中,所有线程共享inputObject,由于入库逻辑较为复杂,所以比较耗时,多次异步调用,每次循环只
会覆盖掉inputObject中封装的数据,所以如果接口很慢的时候,就会出现最后一个线程中的数据覆盖掉前面线程中的数据,导致出现同一数据出现多次入库。
为更直观的解释上面问题,请看如下例子。
1.线程类
import java.util.Map; /** * @ClassName TestThread * @Description screenShot 梦想家 * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt * @Date 2019/1/21 17:12 * @Version 1.0 */ public class TestThread implements Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see Thread#run() */ private Map<String, Object> param; public TestThread(Map param) { this.param = param; } @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.param); } }
2.测试类
package com.zyt.creenshot.service.impl; import com.zyt.creenshot.service.thread.TestThread; import com.zyt.creenshot.util.TaskEngine; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @ClassName TestServiceImpl * @Description screenShot 梦想家 * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt * @Date 2019/1/15 17:34 * @Version 1.0 */ @Service public class TestServiceImpl{ public static void main(String[] args) { testTask(); } public static void testTask(){ List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); list.add("5"); list.add("6"); list.add("7"); list.add("8"); list.add("9"); Map<String,Object> param = new HashMap<>(); for (int i = 0 ;i <3 ; i++) { List<String> sublist = list.subList(i * 3, 3*(i+1)); param.put("subList",sublist); TaskEngine.getInstance().submit(new TestThread(param)); } } }
3.运行输出
4.修改测试类
package com.zyt.creenshot.service.impl; import com.zyt.creenshot.mapper.TestMapper; import com.zyt.creenshot.service.ITestService; import com.zyt.creenshot.service.thread.TestThread; import com.zyt.creenshot.util.TaskEngine; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @ClassName TestServiceImpl * @Description screenShot 梦想家 * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt * @Date 2019/1/15 17:34 * @Version 1.0 */ @Service public class TestServiceImpl implements ITestService { @Autowired(required = false) private TestMapper testMapper; @Override public List test(){ List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); list.add("5"); list.add("6"); list.add("7"); list.add("8"); list.add("9"); List map = testMapper.selectByCount(list); System.out.println(map); return map; } public static void main(String[] args) { testTask(); } public static void testTask(){ List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); list.add("5"); list.add("6"); list.add("7"); list.add("8"); list.add("9"); Map<String,Object> param = new HashMap<>(); for (int i = 0 ;i <3 ; i++) { List<String> sublist = list.subList(i * 3, 3*(i+1)); Map map = (HashMap<String, Object>)((HashMap<String, Object>)param).clone(); map.put("subList",sublist); TaskEngine.getInstance().submit(new TestThread(map)); } } }
5.运行测试
Over 问题解决