对于多线程来说,刚开始是比较蒙的,不了解其中的运行机制。
最近项目中需要用多线程解决一个加载缓慢的问题,特此写了一个例子,供大家参考,如有建议,请多指教,哈哈哈
那么,话不多说。
先说下需求:此接口供xxx公司调用,实现对数据库的读取和修改。而且是全量读取,不进行分页读取。(百万级别数据量)
那就要考虑下,如果将数据分批进行处理,看下哪里运行时间相对较长,将哪部分代码进行多线程处理。
注:程序员最重要的不是写代码,而是对问题的思考和拿出最好的解决方案,再写代码进行解决。
在此例中,将全量数据分批处理,每批5000条数据进行读取操作。
先上代码:
/**
* 查询指定SN的IP值
*
* @return 结果
*/
@RequestMapping("/findIP")
@ResponseBody
public Map<String, Object> getIpFromSn(int flag) {
Map<String, Object> map = new HashMap<String, Object>();
// JSONObject json = null;
try {
//分批进行处理
int total = this.routeInfoService.getRouteFindIPCount();
int onet = 5000;
int begt = 0;
int Wtime = total / onet + 1;
int totalCount = 1;
if (flag == 1) {
KEY_CHECK_DEAL_TYPE = "stop";
} else {
KEY_CHECK_DEAL_TYPE = "deal";
}
for (int j = 1; j <= Wtime; j++) {
logger.info("当前的处理标识为{}"+KEY_CHECK_DEAL_TYPE);
if(KEY_CHECK_DEAL_TYPE.equals("deal")){
begt = (j - 1) * onet;
List<RouteCheckIp> infos = new ArrayList<RouteCheckIp>();
// SimpleDateFormat begint = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Date beginti = begint.parse(begint.format(new Date()));
//查询需要新增处理的SN号码
List<RouteInfo> SnList = this.routeInfoService.selectRouteInfoSn(begt, onet);
// 增加线程,处理循环中的每5000条数据
int threadNum = THREAD_NUM;
ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
CountDownLatch countDownLatch = new CountDownLatch(threadNum);
int perSize = SnList.size() / threadNum;
for (int i = 0; i < threadNum; i++) {
MultiThread thread = new MultiThread();
thread.setRouteInfoList(SnList.subList(i * perSize, (i + 1) * perSize));
thread.setRedisReportUtil(redisReportUtil);
thread.setTotalCount(totalCount);
thread.setTotal(total);
thread.setRouteInfoService(routeInfoService);
thread.setJ(j);
thread.setCountDownLatch(countDownLatch);
executorService.submit(thread);
}
countDownLatch.await();
executorService.shutdown();
// 优化前
// for (RouteInfo info : SnList) {
// String dateBySn = redisReportUtil.getString(CommonConstant.ROUTE_INFO_REPORT_REDIS_PRE + info.getRouteSn());
// if (!"".equals(dateBySn) && (dateBySn != null)) {
// RouteCheckIp rci = new RouteCheckIp();
// json = new JSONObject(dateBySn);
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// String str = json.isNull("routerIp") ? "" : json.get("routerIp").toString();
// int inter = 0;
// if(str==null || str.length()<2){
// inter=3;
// }else if (checkIp("192",str) || checkIp("10",str) || checkIp("100",str) || checkIp("172",str)) {
// inter = 0;
// }else{
// inter=1;
// }
// /**
// * 2018/6/27 新增redis中除去deviceList字段的所有字段
// * 开始
// */
// rci.setWanUpSpeed(json.isNull(