本文共 3356 字,大约阅读时间需要 11 分钟。
声明:本文是《 》的第八章, 作者: Javier Fernández González 译者:郑玉婷
Java 并发 API 提供的其中一个最复杂且强大的功能是使用 Phaser 类来执行同步phased任务。当有些任务可以分成步骤执行时,此机制是很有用的。Phaser类提供的同步线程机制是在每个步骤的末端, 所以全部的线程都完成第一步后,才能开始执行第二步。
在这个指南,你将学习如何从Phaser类获取其状态信息。
准备指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。
怎么做呢…
按照这些步骤来实现下面的例子:
01 | //1. 创建一个类,名为 Task ,实现 Runnable 接口. |
02 | public class Task implements Runnable { |
03 |
04 | //2. 声明一个私有 int 属性,名为 time。 |
05 | private int time; |
06 |
07 | //3. 声明私有 Phaser 属性,名为 phaser. |
08 | private Phaser phaser; |
09 |
10 | //4. 实现类的构造函数,初始其属性值。 |
11 | public Task( int time, Phaser phaser) { |
12 | this .time=time; |
13 | this .phaser=phaser; |
14 | } |
15 |
16 | //5. 实现 run() 方法。首先,使用 arrive() 方法指示 phaser 属性任务开始执行了。 |
17 | @Override |
18 | public void run() { |
19 |
20 | phaser.arrive(); |
21 |
22 | //6. 写信息到操控台表明阶段一开始,把线程放入休眠几秒,使用time属性来表明,再写信息到操控台表明阶段一结束,并使用 phaser 属性的 arriveAndAwaitAdvance() 方法来与剩下的任务同步。 |
23 | System.out.printf( "%s: Entering phase 1.\n" ,Thread. currentThread().getName()); |
24 | try { |
25 | TimeUnit.SECONDS.sleep(time); |
26 | } catch (InterruptedException e) { |
27 | e.printStackTrace(); |
28 | } |
29 | System.out.printf( "%s: Finishing phase 1.\n" ,Thread. currentThread().getName()); |
30 | phaser.arriveAndAwaitAdvance(); |
31 |
32 | //7. 为第二和第三阶段重复第一阶段的行为。在第三阶段的末端使用 arriveAndDeregister()方法代替 arriveAndAwaitAdvance() 方法。 |
33 | System.out.printf( "%s: Entering phase 2.\n" ,Thread. currentThread().getName()); |
34 | try { |
35 | TimeUnit.SECONDS.sleep(time); |
36 | } catch (InterruptedException e) { |
37 | e.printStackTrace(); |
38 | } |
39 | System.out.printf( "%s: Finishing phase 2.\n" ,Thread. currentThread().getName()); |
40 | phaser.arriveAndAwaitAdvance(); |
41 |
42 | System.out.printf( "%s: Entering phase 3.\n" ,Thread. currentThread().getName()); |
43 | try { |
44 | TimeUnit.SECONDS.sleep(time); |
45 | } catch (InterruptedException e) { |
46 | e.printStackTrace(); |
47 | } |
48 | System.out.printf( "%s: Finishing phase 3.\n" ,Thread. currentThread().getName()); |
49 |
50 | phaser.arriveAndDeregister(); |
51 |
52 | //8. 创建例子的主类通过创建一个类,名为 Main 并添加 main()方法。 |
53 | public class Main { |
54 |
55 | public static void main(String[] args) throws Exception { |
56 |
57 | //9. 创建新的有3个参与者的 Phaser 对象,名为 phaser。 |
58 | Phaser phaser= new Phaser( 3 ); |
59 |
60 | //10. 创建并运行3个线程来执行3个task对象。 |
61 | for ( int i= 0 ; i< 3 ; i++) { |
62 | Task task= new Task(i+ 1 , phaser); |
63 | Thread thread= new Thread(task); |
64 | thread.start(); |
65 | } |
66 |
67 | //11.创建迭代10次的for循环,来学关于phaser对象的信息。 |
68 | for ( int i= 0 ; i< 10 ; i++) { |
69 |
70 | //12. 写关于 registered parties 的信息,phaser的phase,到达的parties, 和未到达的parties 的信息。 |
71 | System.out.printf( "********************\n" ); |
72 | System.out.printf( "Main: Phaser Log\n" ); |
73 | System.out.printf( "Main: Phaser: Phase: %d\n" ,phaser.getPhase()); |
74 | System.out.printf( "Main: Phaser: Registered Parties:%d\n" ,phaser.getRegisteredParties()); |
75 | System.out.printf( "Main: Phaser: Arrived Parties:%d\n" ,phaser.getArrivedParties()); |
76 | System.out.printf( "Main: Phaser: Unarrived Parties:%d\n" ,phaser.getUnarrivedParties()); |
77 | System.out.printf( "********************\n" ); |
78 |
79 | //13. 让线程休眠1秒,并合上类的循环。 |
80 | TimeUnit.SECONDS.sleep( 1 ); |
81 | } |
82 | } |
83 | } |
它是如何工作的…
在这个指南,我们在 Task 类实现了 phased 任务。此 phased 任务有3个phases,并使用Phaser接口来与其他Task对象同步。当这些任务正在执行他们的phases时候,主类运行3个任务并打印关于phaser对象的状态信息到操控台。 我们使用以下的方法来获取phaser对象的状态:
以下的裁图展示了项目的部分输出:
参见
转载地址:http://yefyl.baihongyu.com/