用线程池实现多线程向同一个文件写入数据

最近接到一项工作,是要计算某个省的所有县,两两之间的距离。这个排列组合大约有2万条记录。我采取的是百度地图API来查询两个县之间的距离。由于访问百度地图API请求数据,需要一定的时间,所以考虑使用java的线程池创建多线程来完成这一项工作,一边去baidu地图查询结果,一边向CSV文件写入数据。

代码如下:

//用队列存放每一个线程执行的结果值。

Queue result  = new LinkedList();

list = service.getAllData();  //从数据库查询各个省之间的排列组合。

System.out.println("-------"+list.size()); //大约2万条

//建立线程池(固定数量的线程池)

ExecutorService exe = Executors.newFixedThreadPool(20);

//循环list,计算出每两个省之间的距离。

for (final Routes route : list) {

//用Future来接受线程执行返回的结果。

Future a = exe.submit(new Callable() {
public Routes call() {
try {
String name1 = route.getName1();
String name2 = route.getName2();
Map routesMap = new HashMap();
routesMap = service.getRoutesAndTime(name1,name2);
String distance = routesMap.get("distance").toString();
String duration = routesMap.get("duration").toString();
if(distance!=null&&duration!=null)
{
route.setDistance(distance);
route.setDuration(duration);
}
} catch (Exception e) {
e.printStackTrace();
errorList.add(route);
}finally{
}
return route;//返回route对象
}

});

//把线程执行的结果放入到Queue队列中。

result.add(a);
}

//在主线程中执行写入操作

while(!result.isEmpty())
{
//获取队列的头元素
Future future =  result.poll();
Routes route = null;

try {

//用future的get方法来获取route对象。

route = future.get(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

if(route !=null)
{//如果route对象不为空,则执行写操作。
CSVUtil.writeCsv(null,route);
}
}

exe.shutdown();
这样主线程就可以和子线程同时执行,一边访问百度地图Api,一边向CSV文件写入结果。

你可能感兴趣的:(用线程池实现多线程向同一个文件写入数据)