【并发编程】-ExecutorService的方法invokeAny应用

243 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情

ExecutorService的方法应用

接口ExecutorService中有很多工具方法提供使用,invokeAny()方法和invokeAll()方法具有阻塞特性。

​ 方法invokeAny()获取第一个完成任务的结果值,当第一个任务执行完成后,会调用interrupt()方法将其它任务中断,因此在这些任务中可以结合if(Thread.currentThread()..isInterrupted() == true)代码来决定任务是否继续运行。

​ 方法invokeAll()等全部线程任务执行完毕后,获取全部完成任务的返回值。

方法invokeAny(Collection tasks)与interrupt的结合使用

方法invokeAny()获取第一个完成任务的返回值,在这个过程中会发生以下两种情况:

  • 没有使用if(Thread.currentThread().isInterrupted())代码,已经获取第一个运行的返回值后,其他线程继续运行。
  • 有使用if(Thread.currentThread().isInterrupted())代码,已经获取第一个运行的返回值后,其他线程如果使用throw new InterruptedException()代码那么这些线程中断,虽然throw抛出了异常,但在main线程中并不能捕获异常, 如果想要捕获异常,则需要在Callable中使用try-catch显式进行捕获。

线程一执行代码如下:

public class FirstCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        System.out.println(super.getClass().getName()+"  开始时间:  "+System.currentTimeMillis());
        for (int i = 0; i < 1234 ; i++) {
            Math.random();
            Math.random();
            Math.random();
        }
        System.out.println(super.getClass().getName()+"  结束时间:  "+System.currentTimeMillis());
        return super.getClass().getName();
    }
}

线程二执行代码如下:

public class SecondCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println(super.getClass().getName()+" 开始时间: "+System.currentTimeMillis());
        for (int i = 0; i < 1234 ; i++) {
            Math.random();
            Math.random();
            Math.random();
        }
        System.out.println(super.getClass().getName()+" 结束时间: "+System.currentTimeMillis());
        return super.getClass().getName();
    }
}

线程三执行代码如下:

public class ThirdCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println(super.getClass().getName()+" 开始时间: "+System.currentTimeMillis());
        for (int i = 0; i < 1234 ; i++) {
            if(Thread.currentThread().isInterrupted() == false){
                Math.random();
                Math.random();
                Math.random();
            }else{
                System.out.println(super.getClass().getName()+" 抛出异常中断......");
                throw new InterruptedException();
            }
        }
        System.out.println(super.getClass().getName()+" 结束时间: "+System.currentTimeMillis());
        return super.getClass().getName();
    }
}