网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
=================================================================
这两天公司要求也一个工具,对27类资源进行计算,看这个资源属于哪一个网格。
一个资源的数据量大概是1万左右。然后网格的数据大概在5000.也就是说每种资源的每条数据都要个这5000多条的网格进行匹配,正常的话,一条数据找到对应的网格需要1分钟。但是要求整个一晚上跑完。
所以就做了如下调整。
每天定时任务执行一次。获取网格信息和27类资源信息。
然后27类资源分别27个线程处理。然后每个资源中,再分子线程处理,每个子线程处理500条数据,这样1万的数据大概20个线程同时处理。
整个程序跑起来的时候,大概线程数为600。tomcat 一般承受的并发线程数在1600 左右。所以这个方案可行。
===================================================================
@Component
public class GetResourceList {
@Autowired
GetTypeConfig typeConfig;
@Autowired
GetGridList GetGridList;
@Autowired
private JdbcTemplate jdbcTemplate;
public void process(){
List<Map<String, Object>> typeConfigList=typeConfig.getConfigList();
List<Map<String, Object>> gridList=GetGridList.getGridList();
if(typeConfigList==null || typeConfigList.isEmpty() ||gridList==null || gridList.isEmpty()){
return;
}
//new ResourceThread(typeConfigList.get(0),gridList,jdbcTemplate).start();
for(Map<String, Object> map:typeConfigList){
new ResourceThread(map,gridList,jdbcTemplate).start();
}
}
}
typeConfig 是获取27类资源的类型和目标表,后面根据不同的类型获取资源列表。
GetGridList 是网格数据列表。
然后对这27类资源分别用27个线程处理。
@Override
public void run() {
for(int i=0;i<map.size();i++){
String profession=map.get("专业").toString();
String type=map.get("类别").toString();
String tableName=map.get("目标表").toString();
List<Map<String, Object>> resourceList=getListByType(profession,type);
log.info("开始执行:"+tableName+profession+type);
log.info("resourceList:"+resourceList.size());
log.info("gridList:"+list.size());
deletDateFromTable(tableName);
process(resourceList,list,tableName);
}
}
public void process(List<Map<String, Object>> resourceList,List<Map<String, Object>> gridList,String tableName){
if(resourceList==null || resourceList.isEmpty()){
return;
}
int count=resourceList.size()/500 +1;
log.info("线程数"+count);
List<List<Map<String, Object>>> list=ListUtil.averageAssign(resourceList,count);
for(List<Map<String, Object>> temp:list){
new ResourceBranchThread(temp,gridList,jdbcTemplate,tableName).start();
}
}
这里可以看到,对每类资源,再用子线程去处理,每个子线程处理500 条数据。
@Override
public void run() {
if(resourceList==null || resourceList.isEmpty()){
return;
}
for(Map<String, Object> resourceMap:resourceList){
SortResource sortResource=new SortResource(tableName,jdbcTemplate);
sortResource.process(resourceMap,gridList);
}
}
@Slf4j
public class SortResource {
private String tableName;
private JdbcTemplate jdbcTemplate;
public SortResource(String tableName,JdbcTemplate jdbcTemplate){
this.tableName=tableName;
this.jdbcTemplate=jdbcTemplate;
}
public void process(Map<String, Object> map,List<Map<String, Object>> gridList){
log.info("入库表:"+tableName);
double x=Double.parseDouble(map.get("经度").toString());
double y=Double.parseDouble(map.get("纬度").toString());
for(Map<String, Object> gridMap:gridList){
String gridId=gridMap.get("ID").toString();
List<List> lists=lonLatInfoHandle(gridMap.get("经纬度信息").toString());
//log.info("网格ID"+gridId);
if(check(lists,x,y)){
insert(map,gridId);
break;
}
}
}
/**
-
判断点是否在区域内
-
@param lists
-
@param x
-
@param y
-
@return
*/
public boolean check(List<List> lists,double x,double y){
if(lists.isEmpty()){
return false;
}
// 多多边型,有一个为true 就可以
for(List list:lists){
if(checkHbracketsComma(list,x,y)){
return true;
}
}
return false;
}
/**
-
检测镂空的
-
@param list
-
@return
*/
public boolean checkHbracketsComma(List list,double x,double y){
RegionExtern regExt = new RegionExtern(list.get(0));
boolean flag=regExt.checkPointInRegion(x,y);
if(list.size()>1 && flag){
for(int i=1;i<list.size();i++){
RegionExtern regExtTemp = new RegionExtern(list.get(i));
if(regExt.checkPointInRegion(x,y)){
//如果存在镂空的区域内,则返回false;
flag=false;
}
}
}
return flag;
}
/**
-
经纬度信息范围处理
-
@param lonLatInfo
*/
public static List<List> lonLatInfoHandle(String lonLatInfo){
List<List> lists=new ArrayList<>();
if(lonLatInfo==null || lonLatInfo.isEmpty()){
return lists;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!