最近在研究大批量数据处理,在师傅的知道下采用了线程池,对我来说是一次质的飞跃:
public void analyzeDealData()
throws ParseException {
// 第一步:创建表plan_res_mr_indoor plan_res_mr_outdoor
System.out.println("111111第一步开始。。。。。");
this.dao.createTable();
System.out.println("111111第一步结束。。。。。");
// 第二步:批量查处基础数据
System.out.println("222222第二步开始。。。。。");
this.dao.batchInserts();
System.out.println("222222第二步结束。。。。。");
// 第三步:分析处理outdoor 数据(使用多线程做)
System.out.println("33333第三步开始。。。。。");
ExecutorProcessPool pool = ExecutorProcessPool.getInstance();
int count = this.dao.analyzeCellDataCount();
int pageCount = count / 10000 + 1;
for (int j = 0; j < pageCount; j++) {
pool.execute(new AnalyzeDealByPage(j));
}
// 关闭线程池,如果是需要长期运行的线程池,不用调用该方法。
// 监听程序退出的时候最好执行一下。
pool.shutdown();
System.out.println("33333第三步步结束。。。。。");
}
//子线程
/**
* 分析处理数据
*
* @修改人 1527179267@qq.com
* @版本号 0.0.1
* @修改日期: 2016年12月20日 下午3:14:22
* @see [相关类/方法]
* @since [产品/模块版本]
*/
class AnalyzeDealByPage implements Runnable {
private int pageNumber;
public AnalyzeDealByPage(int pageNumber) {
this.pageNumber = pageNumber;
}
@Override
public void run() {
try {
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
int pageSize = 10000;
int pageStartNumber = pageNumber * pageSize - 1;
if (pageNumber == 0) {
pageStartNumber=0;
}
Map<String, Object> param = new HashMap<String, Object>();
param.put("pageSize", pageSize);
param.put("pageStartNumber", pageStartNumber);
List<Map<String, Object>> outDoorList = dao.analyzeCellData(param);
for (int i = 0, h = outDoorList.size() - 1; i < h; i++) {
Map<String, Object> itemOne = outDoorList.get(i);
Map<String, Object> itemTwo = outDoorList.get(i + 1);
String aboutEci = itemOne.get("eci") + "," + itemTwo.get("eci");
String timeBucket = itemOne.get("startTime") + "," + itemTwo.get("startTime");
Double journey =distance(Double.parseDouble(itemOne.get("lng").toString()),Double.parseDouble(itemOne.get("lat").toString()), Double.parseDouble(itemTwo.get("lng").toString()),Double.parseDouble(itemTwo.get("lat").toString()));
Long timDifference = Math.abs(fmt.parse(itemTwo.get("startTime").toString()).getTime()- fmt.parse(itemOne.get("startTime").toString()).getTime());
Double speed = journey / timDifference;
String endLng = itemTwo.get("lng").toString();
String endLat = itemTwo.get("lat").toString();
String endTime = itemTwo.get("startTime").toString();
itemOne.put("aboutEci", aboutEci);
itemOne.put("timeBucket", timeBucket);
itemOne.put("speed", speed);
itemOne.put("endLng", endLng);
itemOne.put("endLat", endLat);
itemOne.put("endTime", endTime);
}
System.out.println("批量更新开始。。。。。。"+(pageNumber+1)+"页更新");
dao.batchUpdates(outDoorList);
System.out.println("批量更新结束。。。。。。end***********************************************"+(pageNumber+1)+"页更新");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
在做很多高并发应用的时候,单线程的瓶颈已经满足不了我们的需求,此时使用多线程来提高处理速度已经是比较常规的方案了。在使用多线程的时候,我们可以使用线程池来管理我们的线程,至于使用线程池的优点就不多说了。
对于多线程的线程安全处理,这个也非常重要,有些同学还是要多补补课。
Java线程池说起来也简单,简单说下继承关系:
ThreadPoolExecutor extends AbstractExecutorService implements ExecutorService extends Executor
还有一个支持延时执行线程和可以重复执行线程的实现类:
ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService
大家把这些类中的相关方法弄清楚,使用线程池就不在话下了。其实弄清楚里面各个方法的功能也就够了。
最重要的还是在实践中总结经验,企业需要的是能实际解决问题的人。
下面是我写的一个例子,包括3个Java文件,分别是:
ExecutorServiceFactory.java
ExecutorProcessPool.java
ExecutorTest.java
下面贴出代码:
1、ExecutorServiceFactory.java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
2、ExecutorProcessPool.java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
3、ExecutorTest.java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
上面代码中也有一些注释说明,自己把代码自己运行一遍看看效果。