62,614
社区成员
发帖
与我相关
我的任务
分享
public Map<String, Object> dataExtract() throws InterruptedException{
// 装载数据表池
DataTabPool.getInstance().loadTabPool();
final ArrayBlockingQueue<String> ABQ = DataTabPool.getInstance().getABQ(); //获取数据表池队列,加载到并行线程中
final Map<String, Object> returnMap = new HashMap<String, Object>();
// 用于存放每层抽取线程任务列表,便于控制所有的线程任务
final List<Future<Map<String, Object>>> list = new ArrayList<Future<Map<String, Object>>>();
// 控制线程并行运行
final CountDownLatch begin = new CountDownLatch(ABQ.size());
// 线程一并等待,同时开始运行。任何一个验证出现错误的时候,能在任务列表中找到任务并停止
final CyclicBarrier barrierOne = new CyclicBarrier(ABQ.size());
// 根据列队大小定义并发线程数
final ExecutorService exec = Executors.newFixedThreadPool(ABQ.size());
// 并行子线程
for (int index = 0; index < ABQ.size(); index++) {
final int NO = index + 1;
if(!DataExtractMain.this.mark){
break;
}
list.add(exec.submit(new Callable<Map<String, Object>>() {
public Map<String, Object> call() throws Exception {
try {
// 如果当前计数为零,则此方法立即返回。
barrierOne.await();
// 动态从池中取出表名
String tableName = DataTabPool.getInstance().takeTab();
System.out.println("No." + NO + " :" + tableName);
// 开始抽数业务代码
Map<String,Object[]> resultMap = new DataExtractWork().extractDataAndSave(tableName) ;
// 当抽取失败的时候,取消任务列表中所有任务,同时修改标记位,停止整个任务管理器,之后的多有操作也不用执行
if (resultMap == null) {
DataExtractMain.this.mark = false;
// 循环遍历停掉管理器中的子线程
for (Future<Map<String, Object>> f : list) {
f.cancel(true);
}
}
} finally {
begin.countDown();
}
return null;
}
}));
}
System.out.println("Extract Start");
begin.await();
System.out.println("Extract Over");
exec.shutdown();
// 判断标志,来决定是否继续后续操作
if (exec.isTerminated()) {
System.out.println("errorList size : " + errorList.size());
return null;
}else{
return returnMap;
}
}
boolean isDone = true;
while(isDone){
for(Future<Map<String,String>> future: futureList){
if(future.isDone()){
// 如果该线程完成了, 则删除该future
futureList.remove(future);
}
if(futureList.size()==0){
// 当线程集合为空时,表示所有线程执行完毕
isDone = false;
break;
}
}
}