码迷,mamicode.com
首页 > 其他好文 > 详细

CompletionService与异常

时间:2021-04-05 12:43:29      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:csr   turn   方法   运行   dem   开始   nbsp   bsp   execution   

 1 package Six_CompletionService_Exception_Demo;
 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         // TODO Auto-generated method stub
10         System.out.println("MyCallableA  begin"+System.currentTimeMillis());
11         Thread.sleep(1000);
12         System.out.println("MyCallableA  end"+System.currentTimeMillis());
13         return "return A";
14     }
15 
16 }
 1 package Six_CompletionService_Exception_Demo;
 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         // TODO Auto-generated method stub
10         System.out.println("MyCallableB  begin" + System.currentTimeMillis());
11         Thread.sleep(5000);
12 
13         int i = 0;
14         if (i == 0) {
15             throw new Exception("抛出异常!!!");
16         }
17 
18         System.out.println("MyCallableB  end" + System.currentTimeMillis());
19         return "return B";
20     }
21 
22 }

Run1:

 1 package Six_CompletionService_Exception_Demo;
 2 
 3 import java.util.concurrent.CompletionService;
 4 import java.util.concurrent.Executor;
 5 import java.util.concurrent.ExecutorCompletionService;
 6 import java.util.concurrent.Executors;
 7 
 8 public class Run1 {
 9 
10     public static void main(String[] args) {
11 
12         try {
13 
14             MyCallableA mA = new MyCallableA();
15             MyCallableB mB = new MyCallableB();
16 
17             // 创建单一线程池,一次最多运行一个线程
18             Executor executor = Executors.newSingleThreadExecutor();
19 
20             CompletionService csRef = new ExecutorCompletionService(executor);
21 
22             csRef.submit(mA);
23             csRef.submit(mB);
24 
25             for (int i = 0; i < 2; i++) {
26 
27                 System.out.println("zzzzzzzz" + "  " + csRef.take());
28             }
29             System.out.println("main end!!!");
30         } catch (InterruptedException e) {
31             // TODO Auto-generated catch block
32             e.printStackTrace();
33         }
34     }
35 
36 }

运行结果:

技术图片

分析:

  虽然MyCallable中有异常,但是主线程中只是使用了take()方法,即取到最先完成任务的对象,没有调用FutureTask类的get()方法,所以不出现异常。这里线程B虽然抛出异常,但是它一抛出异常也意味着执行完毕,所以这里使用take()方法获取到了2个对象。

Run2:

 1 package Six_CompletionService_Exception_Demo;
 2 
 3 import java.util.concurrent.CompletionService;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.Executor;
 6 import java.util.concurrent.ExecutorCompletionService;
 7 import java.util.concurrent.Executors;
 8 
 9 public class Run2 {
10 
11     public static void main(String[] args) {
12 
13         try {
14 
15             MyCallableA mA = new MyCallableA();
16             MyCallableB mB = new MyCallableB();
17 
18             // 创建单一线程池,一次最多运行一个线程
19             Executor executor = Executors.newSingleThreadExecutor();
20 
21             CompletionService csRef = new ExecutorCompletionService(executor);
22             
23 
24             /*
25              * 因为这里创建的是单一线程,这意味着,线程池中最多执行1个线程,所以下面两个线程需要排队执行
26              */
27             csRef.submit(mA);// 先执行A
28             csRef.submit(mB);// 再执行B
29 
30             for (int i = 0; i < 2; i++) {
31 
32                 System.out.println("zzzzzzzz" + "  " + csRef.take().get());
33             }
34             System.out.println("main end!!!");
35         } catch (InterruptedException e) {
36             // TODO Auto-generated catch block
37             e.printStackTrace();
38         } catch (ExecutionException e) {
39             // TODO Auto-generated catch block
40             e.printStackTrace();
41         }
42     }
43 
44 }

运行结果:

技术图片

 

分析:

  因为这里创建的是单一线程,这意味着,线程池中最多执行1个线程,所以A、B两个线程需要排队执行。A执行完毕B再执行。

  最终的结果就是:A正常执行,B出现异常.因为A执行时间较少,只有1s钟,而且也没有异常,所以正确打印线程A的返回值,线程B出现异常。

 

 

Run3:

 1 package Six_CompletionService_Exception_Demo;
 2 
 3 import java.util.concurrent.CompletionService;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.Executor;
 6 import java.util.concurrent.ExecutorCompletionService;
 7 import java.util.concurrent.Executors;
 8 
 9 public class Run3 {
10 
11     public static void main(String[] args) {
12 
13         try {
14 
15             MyCallableA mA = new MyCallableA();
16             MyCallableB mB = new MyCallableB();
17 
18             // 创建单一线程池,一次最多运行一个线程
19             Executor executor = Executors.newSingleThreadExecutor();
20 
21             CompletionService csRef = new ExecutorCompletionService(executor);
22 
23             /*
24              * 因为这里创建的是单一线程,这意味着,线程池中最多执行1个线程,所以下面两个线程需要排队执行
25              */
26             csRef.submit(mB);// 先执行B
27             csRef.submit(mA);// 再执行A
28 
29             for (int i = 0; i < 2; i++) {
30 
31                 System.out.println("zzzzzzzz" + "  " + csRef.take().get());
32             }
33             System.out.println("main end!!!");
34         } catch (InterruptedException e) {
35             // TODO Auto-generated catch block
36             e.printStackTrace();
37         } catch (ExecutionException e) {
38             // TODO Auto-generated catch block
39             e.printStackTrace();
40         }
41     }
42 
43 }

运行结果:

技术图片

  

分析:

  线程B先运行,运行过程中遇到异常,并抛出,线程B运行完毕,然后A开始运行。

  最终的结果:B出现异常,A线程未输出

 

Run4:

  

 1 package Six_CompletionService_Exception_Demo;
 2 
 3 import java.util.concurrent.CompletionService;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.Executor;
 6 import java.util.concurrent.ExecutorCompletionService;
 7 import java.util.concurrent.Executors;
 8 
 9 public class Run4 {
10 
11     public static void main(String[] args) {
12 
13         try {
14 
15             MyCallableA mA = new MyCallableA();
16             MyCallableB mB = new MyCallableB();
17 
18             // 创建单一线程池,一次最多运行一个线程
19             Executor executor = Executors.newSingleThreadExecutor();
20 
21             CompletionService csRef = new ExecutorCompletionService(executor);
22 
23             /*
24              * 因为这里创建的是单一线程,这意味着,线程池中最多执行1个线程,所以下面两个线程需要排队执行
25              */
26             csRef.submit(mA);// 先执行A
27             csRef.submit(mB);// 再执行B
28 
29             for (int i = 0; i < 2; i++) {
30 
31                 System.out.println("zzzzzzzz" + "  " + csRef.poll());
32             }
33 
34             Thread.sleep(6000);
35 
36             System.out.println("A处" + " " + csRef.poll());
37             System.out.println("A处" + " " + csRef.poll());
38             System.out.println("main end!!!");
39         } catch (InterruptedException e) {
40             // TODO Auto-generated catch block
41             e.printStackTrace();
42         }
43     }
44 
45 }

运行结果:

技术图片

Run 5:

 1 package Six_CompletionService_Exception_Demo;
 2 
 3 import java.util.concurrent.CompletionService;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.Executor;
 6 import java.util.concurrent.ExecutorCompletionService;
 7 import java.util.concurrent.Executors;
 8 
 9 public class Run4 {
10 
11     public static void main(String[] args) {
12 
13         try {
14 
15             MyCallableA mA = new MyCallableA();
16             MyCallableB mB = new MyCallableB();
17 
18             // 创建单一线程池,一次最多运行一个线程
19             Executor executor = Executors.newSingleThreadExecutor();
20 
21             CompletionService csRef = new ExecutorCompletionService(executor);
22 
23             /*
24              * 因为这里创建的是单一线程,这意味着,线程池中最多执行1个线程,所以下面两个线程需要排队执行
25              */
26             csRef.submit(mA);// 先执行A
27             csRef.submit(mB);// 再执行B
28 
29             for (int i = 0; i < 2; i++) {
30 
31                 System.out.println("zzzzzzzz" + "  " + csRef.poll());
32             }
33 
34             Thread.sleep(6000);
35 
36             System.out.println("A处" + " " + csRef.poll().get());
37             System.out.println("B处" + " " + csRef.poll().get());
38             
39             System.out.println("main end!!!");
40         } catch (InterruptedException e) {
41             // TODO Auto-generated catch block
42             e.printStackTrace();
43         } catch (ExecutionException e) {
44             // TODO Auto-generated catch block
45             e.printStackTrace();
46         }
47     }
48 
49 }

运行结果:

技术图片

  打印线程A的返回值,线程B出现异常

Run6:

 1 package Six_CompletionService_Exception_Demo;
 2 
 3 import java.util.concurrent.CompletionService;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.Executor;
 6 import java.util.concurrent.ExecutorCompletionService;
 7 import java.util.concurrent.Executors;
 8 
 9 public class Run6 {
10 
11     public static void main(String[] args) {
12 
13         try {
14 
15             MyCallableA mA = new MyCallableA();
16             MyCallableB mB = new MyCallableB();
17 
18             // 创建单一线程池,一次最多运行一个线程
19             Executor executor = Executors.newSingleThreadExecutor();
20 
21             CompletionService csRef = new ExecutorCompletionService(executor);
22 
23             /*
24              * 因为这里创建的是单一线程,这意味着,线程池中最多执行1个线程,所以下面两个线程需要排队执行
25              */
26             csRef.submit(mB);// 先执行B
27             csRef.submit(mA);// 再执行A
28 
29             for (int i = 0; i < 2; i++) {
30 
31                 System.out.println("zzzzzzzz" + "  " + csRef.poll());
32             }
33 
34             Thread.sleep(6000);
35 
36             System.out.println("A处" + " " + csRef.poll().get());
37             System.out.println("B处" + " " + csRef.poll().get());
38 
39             System.out.println("main end!!!");
40         } catch (InterruptedException e) {
41             // TODO Auto-generated catch block
42             e.printStackTrace();
43         } catch (ExecutionException e) {
44             // TODO Auto-generated catch block
45             e.printStackTrace();
46         }
47     }
48 
49 }

运行结果:

技术图片

 

  线程A未打印,线程B抛出异常

CompletionService与异常

标签:csr   turn   方法   运行   dem   开始   nbsp   bsp   execution   

原文地址:https://www.cnblogs.com/Leeyoung888/p/14614276.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!