一、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 {&#64;Overridepublic String call() throws Exception {System.out.println("CallableA begin:" &#43; System.currentTimeMillis());for (int i &#61; 0; i <1000; i&#43;&#43;) {System.out.println("A:" &#43; i);}System.out.println("CallableA end:" &#43; System.currentTimeMillis());return "call A";}
}
package invoke;import java.util.concurrent.Callable;/*** &#64;Author: jiaqing.xu&#64;hand-china.com* &#64;Date: 2019-04-07 21:43* &#64;Description*/
public class MyCallableB implements Callable {&#64;Overridepublic String call() throws Exception {System.out.println("CallableB begin:" &#43; System.currentTimeMillis());for (int i &#61; 0; i <1000; i&#43;&#43;) {System.out.println("B:" &#43; i);}System.out.println("CallableB end:" &#43; 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;/*** &#64;Author: jiaqing.xu&#64;hand-china.com* &#64;Date: 2019-04-07 21:46* &#64;Description*/
public class RunMain1 {public static void main(String[] args) {List list &#61; new ArrayList();list.add(new MyCallableA());list.add(new MyCallableB());ExecutorService executorService &#61; Executors.newCachedThreadPool();try {String getValueA &#61; (String) executorService.invokeAny(list);System.out.println(getValueA);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
}
结果不会因为A的invokeAny而导致&#xff0c;B的终止&#xff1a;
但是&#xff0c;如果将MyCallableB改造成如下形式&#xff1a;
import java.util.concurrent.Callable;/*** &#64;Author: jiaqing.xu&#64;hand-china.com* &#64;Date: 2019-04-07 21:43* &#64;Description*/
public class MyCallableB implements Callable {&#64;Overridepublic String call() throws Exception {System.out.println("CallableB begin:" &#43; System.currentTimeMillis());for (int i &#61; 0; i <1000; i&#43;&#43;) {if (!Thread.currentThread().isInterrupted()) {System.out.println("B:" &#43; i);} else {System.out.println("开始抛出异常...");throw new InterruptedException("异常");}}System.out.println("CallableB end:" &#43; System.currentTimeMillis());return "call B";}
}
A线程会正常执行完毕&#xff0c;但是B线程会因为A的invokeAny而终止执行&#xff1a;
二、invokeAll()方法
作用&#xff1a;返回所有任务的执行结果&#xff0c;该方法的执行效果也是阻塞执行的&#xff0c;要把所有的结果都取回时再继续向下执行。
MyCallableA等待3s:
package invoke;import java.util.concurrent.Callable;/*** &#64;Author: jiaqing.xu&#64;hand-china.com* &#64;Date: 2019-04-07 21:41* &#64;Description*/
public class MyCallableA implements Callable {&#64;Overridepublic String call() throws Exception {System.out.println("CallableA begin:" &#43; System.currentTimeMillis()); Thread.sleep(3000);System.out.println("CallableA end:" &#43; System.currentTimeMillis());return "call A";}
}
MyCallableB等待5s:
package invoke;import java.util.concurrent.Callable;/*** &#64;Author: jiaqing.xu&#64;hand-china.com* &#64;Date: 2019-04-07 21:43* &#64;Description*/
public class MyCallableB implements Callable {&#64;Overridepublic String call() throws Exception {System.out.println("CallableB begin:" &#43; System.currentTimeMillis());Thread.sleep(5000);System.out.println("CallableB end:" &#43; 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;
/*** &#64;Author: jiaqing.xu&#64;hand-china.com* &#64;Date: 2019-04-07 22:06* &#64;Description*/
public class RunMain2 {public static void main(String[] args) throws InterruptedException {MyCallableA myCallableA &#61; new MyCallableA();MyCallableB myCallableB &#61; new MyCallableB();List> callableList &#61; new ArrayList<>();callableList.add(myCallableA);callableList.add(myCallableB);ExecutorService executorService &#61; Executors.newCachedThreadPool();//开始时间Long startTime &#61; System.currentTimeMillis();System.out.println("invoke all begin: " &#43; startTime);//invokeAll等到两个线程的返回 它是阻塞的List> futureList &#61; executorService.invokeAll(callableList);//结束时间Long endTime &#61; System.currentTimeMillis();System.out.println("invoke all end: " &#43; endTime);//输出最后的耗时System.out.println("all time: " &#43; (endTime - startTime) / 1000 &#43; "s");}
}