Java并发编程系列学习_invokeAny()方法与invokeAll()方法

一、invokeAny()方法

作用:取得第一个完成任务的结果值,当第一个任务执行完成后,会调用interrupt方法将其他的任务中断。

在这里会出现两种情况:

  • 无 Thread.currentThread().isInterrupted() 的判断,则已经获得第一个运行的结果的值后,其他线程继续运行;
  • 有 Thread.currentThread().isInterrupted() 的判断,再结合new InterruptedException使得这些线程中断;

例子如下:

package invoke;

import java.util.concurrent.Callable;

/**
 * @Author: jiaqing.xu@hand-china.com
 * @Date: 2019-04-07 21:41
 * @Description
 */
public class MyCallableA implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("CallableA begin:" + System.currentTimeMillis());

        for (int i = 0; i < 1000; i++) {
            System.out.println("A:" + i);
        }

        System.out.println("CallableA end:" + System.currentTimeMillis());

        return "call A";
    }
}
package invoke;

import java.util.concurrent.Callable;

/**
 * @Author: jiaqing.xu@hand-china.com
 * @Date: 2019-04-07 21:43
 * @Description
 */
public class MyCallableB implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("CallableB begin:" + System.currentTimeMillis());

        for (int i = 0; i < 1000; i++) {
            System.out.println("B:" + i);
        }

        System.out.println("CallableB end:" + System.currentTimeMillis());

        return "call B";
    }
}
package invoke;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: jiaqing.xu@hand-china.com
 * @Date: 2019-04-07 21:46
 * @Description
 */
public class RunMain1 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new MyCallableA());
        list.add(new MyCallableB());
        ExecutorService executorService = Executors.newCachedThreadPool();
        try {
            String getValueA = (String) executorService.invokeAny(list);
            System.out.println(getValueA);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

结果不会因为A的invokeAny而导致,B的终止:

但是,如果将MyCallableB改造成如下形式:

import java.util.concurrent.Callable;

/**
 * @Author: jiaqing.xu@hand-china.com
 * @Date: 2019-04-07 21:43
 * @Description
 */
public class MyCallableB implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("CallableB begin:" + System.currentTimeMillis());

        for (int i = 0; i < 1000; i++) {
            if (!Thread.currentThread().isInterrupted()) {
                System.out.println("B:" + i);
            } else {
                System.out.println("开始抛出异常...");
                throw new InterruptedException("异常");
            }
        }

        System.out.println("CallableB end:" + System.currentTimeMillis());

        return "call B";
    }
}

A线程会正常执行完毕,但是B线程会因为A的invokeAny而终止执行:

二、invokeAll()方法

作用:返回所有任务的执行结果,该方法的执行效果也是阻塞执行的,要把所有的结果都取回时再继续向下执行。

MyCallableA等待3s:

package invoke;

import java.util.concurrent.Callable;

/**
 * @Author: jiaqing.xu@hand-china.com
 * @Date: 2019-04-07 21:41
 * @Description
 */
public class MyCallableA implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("CallableA begin:" + System.currentTimeMillis());   
        Thread.sleep(3000);
        System.out.println("CallableA end:" + System.currentTimeMillis());
        return "call A";
    }
}

MyCallableB等待5s:

package invoke;

import java.util.concurrent.Callable;

/**
 * @Author: jiaqing.xu@hand-china.com
 * @Date: 2019-04-07 21:43
 * @Description
 */
public class MyCallableB implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("CallableB begin:" + System.currentTimeMillis());
        Thread.sleep(5000);
        System.out.println("CallableB end:" + System.currentTimeMillis());
        return "call B";
    }
}
package invoke;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
 * @Author: jiaqing.xu@hand-china.com
 * @Date: 2019-04-07 22:06
 * @Description
 */
public class RunMain2 {
    public static void main(String[] args) throws InterruptedException {
        MyCallableA myCallableA = new MyCallableA();
        MyCallableB myCallableB = new MyCallableB();
        List<Callable<String>> callableList = new ArrayList<>();
        callableList.add(myCallableA);
        callableList.add(myCallableB);
        ExecutorService executorService = Executors.newCachedThreadPool();
        //开始时间
        Long startTime = System.currentTimeMillis();
        System.out.println("invoke all begin: " + startTime);
        //invokeAll等到两个线程的返回 它是阻塞的
        List<Future<String>> futureList = executorService.invokeAll(callableList);
        //结束时间
        Long endTime = System.currentTimeMillis();
        System.out.println("invoke all end: " + endTime);
        //输出最后的耗时
        System.out.println("all time: " + (endTime - startTime) / 1000 + "s");
    }
}

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值