java 多线程全部执行完后再继续进行后门的方法

今天面试一家互联网公司,被虐的有点体无完肤,后来查询资料来总结下。
我们知道,当不使用线程池时,想让A线程在B线程执行完之后执行,需要在A中的某个调用处,调用B.join,但如果使用jdk1.5以后提供的线程池ExecutorService,这个就用不上了,用了会出同步问题,其实这个场景应该是很常见的吧,比如你用多线程并发执行一些操作,当这些操作全部完成时才能进行下一步,这就是需要这个功能了。后来偶然在网上看到有人说用ExecutorService.invokeAll可以实现,测试了一下,确实简单。这个方法的定义如下:

[java] view plaincopy
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;

你需要传一个Callable实现类元素的集合给此方法,每个元素就是一个线程了,返回值是线程执行结果的集合,声明的异常,按照文档的说法---if interrupted while waiting, in which case unfinished tasks are cancelled,如果执行时出现了中断异常,其它未执行完的线程会取消,但我经过测试,发现并没有取消,仍旧正常执行了。下面给出个小例子:

package com.lx.thread.afterAllThreadOver1;

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class InvokeAllTest {
public static void main(String[] args) throws Exception {
ExecutorService pool = Executors.newCachedThreadPool();

ArrayList<Callable<Integer>> callers = new ArrayList<Callable<Integer>>();
long tStart = System.currentTimeMillis();
int len = 200;
final Random rnd = new Random(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
callers.add(new Callable() {
public Object call() throws Exception {
String name = Thread.currentThread().getName();
int num = rnd.nextInt(10);
//如果生成的随机数大于5,就抛出个异常,
//但此异常并不会被主程序catch到,谁能告诉我为什么???
if (num > 5) {
System.out.println("exception:----");
throw new InterruptedException(name);
}
Thread.sleep(10000);
System.out.println(name);
return null;
}
});
}
pool.invokeAll(callers);
long tEnd = System.currentTimeMillis();
System.out.println("总共用时:"+ (tEnd - tStart) + "millions");
System.out.println("done!");
pool.shutdown();
}
}




逻辑极其简单,启动200个线程,每个线程先生成一个随机数,如果大于5就抛出异常,中止,否则,睡10秒钟,再输出自己的名字。如果输出结果是200条,说明不管有没有线程抛出异常,其它异常仍旧会照常执行,使用完毕后一定要记得shutdown线程池,否则程序一直挂在那儿无法终止。运行结果,done总是在最后一行输出,说明它总是等池里的所有线程执行完后才会执行到这一步,这样你就可以把第二步的逻辑写到这里就行了。解决了很大的问题。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值