简单说下业务需求,多线程处理任务,单个线程处理时间超过两小时,叉掉此线程的任务。如此简单,以下是处理办法与思路,但是没想到踩坑了,有大佬有好的想法请评论区留言,不胜感激
#简单粗暴的创建多线程
// TODO 创建20个线程
ExecutorService es = Executors.newFixedThreadPool(4);
// TODO 调多线程
private void deal(List<E> list,int n){
final CountDownLatch countDownLatch = new CountDownLatch(n);
final Iterator<E> it = list.iterator();
es.submit(new Runnable(){
@overrive
public void run(){
while(it.hasNext()){
try{
// todo 处理逻辑
} catch (Exception e) {
e.printStackTrace();
}
}
countDownLatch.countDown();
}
});
//线程等待超时
try{
if(!countDownLatch.await(2*60*60, TimeUnit.SECONDS)) {
// TODO 结束所有线程
es.shutdown();
}
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
发现单次处理的话没有问题,shutdown()之后,业务确实没有继续处理,但是当数据多的时候,就是分批次调用这个多线程方法的时候,之前停掉的任务会继续处理,这就比较蛋疼(具体看需求)。
想到的方法是
在线程之前加一个逻辑中断标志
final Boolean[] flag = new Boolean[1];
flag[0] = true;
然后再while中的条件 &&上 (flag[0] == true)
在超时的代码中把 es.shutdown(); 替换为flag[0]=false; 这样线程不用杀,任务也可以逻辑过滤掉不再执行了(其实执行了,但是业务什么也没有处理。)