invokeAny与执行快的任务异常

 1 package Seven_invokeAny_Fast_Demo1;
 2 
 3 import java.util.concurrent.Callable;
 4 
 5 public class MyCallableA implements Callable<String> {
 6 
 7     @Override
 8     public String call() throws Exception {
 9         System.out.println("MyCallableA" + Thread.currentThread().getName() + " begin " + System.currentTimeMillis());
10         for (int i = 0; i < 123; i++) {
11             String newString = new String();
12             Math.random();
13             Math.random();
14             Math.random();
15             Math.random();
16             Math.random();
17             System.out.println("MyCallableA 在运行中= " + (i + 1));
18         }
19 
20         if (1 == 1) {
21             System.out.println("xxxxxxxxxxx=中断了");
22             throw new NullPointerException();
23         }
24 
25         System.out.println("MyCallableA" + Thread.currentThread().getName() + " end " + System.currentTimeMillis());
26 
27         return "return---A";
28     }
29 
30 }
 1 package Seven_invokeAny_Fast_Demo1;
 2 
 3 import java.util.concurrent.Callable;
 4 
 5 public class MyCallableB implements Callable<String> {
 6 
 7     @Override
 8     public String call() throws Exception {
 9         System.out.println("MyCallableB" + Thread.currentThread().getName() + " begin " + System.currentTimeMillis());
10         for (int i = 0; i < 223; i++) {
11             String newString = new String();
12             Math.random();
13             Math.random();
14             Math.random();
15             Math.random();
16             Math.random();
17             System.out.println("MyCallableB 在运行中= " + (i + 1));
18         }
19 
20         System.out.println("MyCallableB" + Thread.currentThread().getName() + " end " + System.currentTimeMillis());
21 
22         return "return---B";
23     }
24 
25 }
 1 package Seven_invokeAny_Fast_Demo1;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 import java.util.concurrent.ExecutionException;
 6 import java.util.concurrent.ExecutorService;
 7 import java.util.concurrent.Executors;
 8 
 9 public class Run {
10 
11     public static void main(String[] args) {
12         try {
13 
14             List list = new ArrayList();
15 
16             list.add(new MyCallableB());
17             list.add(new MyCallableA());
18 
19             ExecutorService service = Executors.newCachedThreadPool();
20 
21             String getString;
22 
23             getString = (String) service.invokeAny(list);
24             System.out.println("main取得返回值=" + getString);
25         } catch (InterruptedException e) {
26             System.out.println("main Interrupted_Exception");
27             e.printStackTrace();
28         } catch (ExecutionException e) {
29             System.out.println("main Execution_Exception");
30             e.printStackTrace();
31         }
32 
33     }
34 
35 }

运行结果:

                                                                                                               

分析:

  线程A是执行快的线程,线程B是执行慢的线程。线程A中断了,所以主线程中没有获取到A的返回值,线程A先执行完毕后,线程池将B设置为中断interrupte,但是线程B中没有对这个中断进行处理,所以线程B继续执行,不受影响。最终的结果是,线程B正常执行完毕,主线程中获取到线程B中return的值。

(2)倘若在执行快的线程A中,使用try_catch的方式对中断异常进行捕获

 1 package Seven_invokeAny_Fast_Demo1;
 2 
 3 import java.util.concurrent.Callable;
 4 
 5 public class MyCallableA implements Callable<String> {
 6 
 7     @Override
 8     public String call() throws Exception {
 9         System.out.println("MyCallableA" + Thread.currentThread().getName() + " begin " + System.currentTimeMillis());
10         
11         try{
12         for (int i = 0; i < 123; i++) {
13             String newString = new String();
14             Math.random();
15             Math.random();
16             Math.random();
17             Math.random();
18             Math.random();
19             System.out.println("MyCallableA 在运行中= " + (i + 1));
20         }
21 
22         if (1 == 1) {
23             System.out.println("xxxxxxxxxxx=中断了");
24             throw new NullPointerException();
25         }
26 
27         System.out.println("MyCallableA" + Thread.currentThread().getName() + " end " + System.currentTimeMillis());
28         }catch(Exception e){
29             System.out.println(e.getMessage()+" : 左边信息就是捕获的异常信息");
30         }
31 
32         return "return---A";
33     }
34 
35 }

运行结果:

                                                  

 

分析:

  在A中进行了try_catch捕获中断异常,但是没有进行重新抛出异常。所带来的结果就是,主线程main获取到的不是没有异常的B线程的返回值,而是有中断异常的A线程的返回值。

  这是因为,A线程虽然有中断异常,但是用try_cathch捕获后却没有重新抛出异常。导致主线程main误认为线程A是正确的,所以主线程main正常获取A的返回值,至于线程B,因为没有 对invokeAny()获取到第一个值(线程A的返回值)后调用的interrupt()方法发出的中断进行处理,所以线程B正常运行,只是最终主线程不获取线程B的返回值而已(因为之前主线程已经获取了线程A的返回值)。

(3)在线程A中,使用try_catch捕获中断异常后又重新抛出

 1 package Seven_invokeAny_Fast_Demo1;
 2 
 3 import java.util.concurrent.Callable;
 4 
 5 public class MyCallableA implements Callable<String> {
 6 
 7     @Override
 8     public String call() throws Exception {
 9         System.out.println("MyCallableA" + Thread.currentThread().getName() + " begin " + System.currentTimeMillis());
10         
11         try{
12         for (int i = 0; i < 123; i++) {
13             String newString = new String();
14             Math.random();
15             Math.random();
16             Math.random();
17             Math.random();
18             Math.random();
19             System.out.println("MyCallableA 在运行中= " + (i + 1));
20         }
21 
22         if (1 == 1) {
23             System.out.println("xxxxxxxxxxx=中断了");
24             throw new NullPointerException();
25         }
26 
27         System.out.println("MyCallableA" + Thread.currentThread().getName() + " end " + System.currentTimeMillis());
28         }catch(Exception e){
29             System.out.println(e.getMessage()+" : 左边信息就是捕获的异常信息");
30             
31             throw e;//重新抛出异常
32         }
33 
34         return "return---A";
35     }
36 
37 }

 

 

运行结果:

                                         

分析:

  可以看到线程A通过try_catch捕获到中断异常,有采用 throw e将这个异常抛出,主线程main中就不会获得A的返回值,而是获得B的返回值

 

posted @ 2021-04-04 15:35  L1998  阅读(117)  评论(0)    收藏  举报