java 并发 api 提供的其中一个最复杂且强大的功能是使用 phaser 类来执行同步phased任务。当有些任务可以分成步骤执行时,此机制是很有用的。phaser类提供的同步线程机制是在每个步骤的末端, 所以全部的线程都完成第一步后,才能开始执行第二步。
在这个指南,你将学习如何从phaser类获取其状态信息。
准备
指南中的例子是使用eclipse ide 来实现的。如果你使用eclipse 或者其他的ide,例如netbeans, 打开并创建一个新的java项目。
怎么做呢…
按照这些步骤来实现下面的例子:
<code>01</code>
<code>//1. 创建一个类,名为 task ,实现 runnable 接口.</code>
<code>02</code>
<code>public</code> <code>class</code> <code>task </code><code>implements</code> <code>runnable {</code>
<code>03</code>
<code>04</code>
<code>//2. 声明一个私有 int 属性,名为 time。</code>
<code>05</code>
<code>private</code> <code>int</code> <code>time;</code>
<code>06</code>
<code>07</code>
<code>//3. 声明私有 phaser 属性,名为 phaser.</code>
<code>08</code>
<code>private</code> <code>phaser phaser;</code>
<code>09</code>
<code>10</code>
<code>//4. 实现类的构造函数,初始其属性值。</code>
<code>11</code>
<code>public</code> <code>task(</code><code>int</code> <code>time, phaser phaser) {</code>
<code>12</code>
<code> </code><code>this</code><code>.time=time;</code>
<code>13</code>
<code> </code><code>this</code><code>.phaser=phaser;</code>
<code>14</code>
<code>}</code>
<code>15</code>
<code>16</code>
<code>//5. 实现 run() 方法。首先,使用 arrive() 方法指示 phaser 属性任务开始执行了。</code>
<code>17</code>
<code>@override</code>
<code>18</code>
<code>public</code> <code>void</code> <code>run() {</code>
<code>19</code>
<code>20</code>
<code> </code><code>phaser.arrive();</code>
<code>21</code>
<code>22</code>
<code>//6. 写信息到操控台表明阶段一开始,把线程放入休眠几秒,使用time属性来表明,再写信息到操控台表明阶段一结束,并使用 phaser 属性的 arriveandawaitadvance() 方法来与剩下的任务同步。</code>
<code>23</code>
<code>system.out.printf(</code><code>"%s: entering phase 1.\n"</code><code>,thread. currentthread().getname());</code>
<code>24</code>
<code>try</code> <code>{</code>
<code>25</code>
<code> </code><code>timeunit.seconds.sleep(time);</code>
<code>26</code>
<code>} </code><code>catch</code> <code>(interruptedexception e) {</code>
<code>27</code>
<code> </code><code>e.printstacktrace();</code>
<code>28</code>
<code>29</code>
<code>system.out.printf(</code><code>"%s: finishing phase 1.\n"</code><code>,thread. currentthread().getname());</code>
<code>30</code>
<code>phaser.arriveandawaitadvance();</code>
<code>31</code>
<code>32</code>
<code>//7. 为第二和第三阶段重复第一阶段的行为。在第三阶段的末端使用 arriveandderegister()方法代替 arriveandawaitadvance() 方法。</code>
<code>33</code>
<code>system.out.printf(</code><code>"%s: entering phase 2.\n"</code><code>,thread. currentthread().getname());</code>
<code>34</code>
<code>35</code>
<code>36</code>
<code>37</code>
<code>38</code>
<code>39</code>
<code>system.out.printf(</code><code>"%s: finishing phase 2.\n"</code><code>,thread. currentthread().getname());</code>
<code>40</code>
<code>41</code>
<code>42</code>
<code>system.out.printf(</code><code>"%s: entering phase 3.\n"</code><code>,thread. currentthread().getname());</code>
<code>43</code>
<code>44</code>
<code>45</code>
<code>46</code>
<code>47</code>
<code>48</code>
<code>system.out.printf(</code><code>"%s: finishing phase 3.\n"</code><code>,thread. currentthread().getname());</code>
<code>49</code>
<code>50</code>
<code>phaser.arriveandderegister();</code>
<code>51</code>
<code>52</code>
<code>//8. 创建例子的主类通过创建一个类,名为 main 并添加 main()方法。</code>
<code>53</code>
<code>public</code> <code>class</code> <code>main {</code>
<code>54</code>
<code>55</code>
<code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) </code><code>throws</code> <code>exception {</code>
<code>56</code>
<code>57</code>
<code>//9. 创建新的有3个参与者的 phaser 对象,名为 phaser。</code>
<code>58</code>
<code>phaser phaser=</code><code>new</code> <code>phaser(</code><code>3</code><code>);</code>
<code>59</code>
<code>60</code>
<code>//10. 创建并运行3个线程来执行3个task对象。</code>
<code>61</code>
<code>for</code> <code>(</code><code>int</code> <code>i=</code><code>0</code><code>; i<</code><code>3</code><code>; i++) {</code>
<code>62</code>
<code> </code><code>task task=</code><code>new</code> <code>task(i+</code><code>1</code><code>, phaser);</code>
<code>63</code>
<code> </code><code>thread thread=</code><code>new</code> <code>thread(task);</code>
<code>64</code>
<code> </code><code>thread.start();</code>
<code>65</code>
<code>66</code>
<code>67</code>
<code>//11.创建迭代10次的for循环,来学关于phaser对象的信息。</code>
<code>68</code>
<code>for</code> <code>(</code><code>int</code> <code>i=</code><code>0</code><code>; i<</code><code>10</code><code>; i++) {</code>
<code>69</code>
<code>70</code>
<code>//12. 写关于 registered parties 的信息,phaser的phase,到达的parties, 和未到达的parties 的信息。</code>
<code>71</code>
<code>system.out.printf(</code><code>"********************\n"</code><code>);</code>
<code>72</code>
<code>system.out.printf(</code><code>"main: phaser log\n"</code><code>);</code>
<code>73</code>
<code>system.out.printf(</code><code>"main: phaser: phase: %d\n"</code><code>,phaser.getphase());</code>
<code>74</code>
<code>system.out.printf(</code><code>"main: phaser: registered parties:%d\n"</code><code>,phaser.getregisteredparties());</code>
<code>75</code>
<code>system.out.printf(</code><code>"main: phaser: arrived parties:%d\n"</code><code>,phaser.getarrivedparties());</code>
<code>76</code>
<code>system.out.printf(</code><code>"main: phaser: unarrived parties:%d\n"</code><code>,phaser.getunarrivedparties());</code>
<code>77</code>
<code>78</code>
<code>79</code>
<code>//13. 让线程休眠1秒,并合上类的循环。</code>
<code>80</code>
<code>timeunit.seconds.sleep(</code><code>1</code><code>);</code>
<code>81</code>
<code>82</code>
<code>83</code>
它是如何工作的…
在这个指南,我们在 task 类实现了 phased 任务。此 phased 任务有3个phases,并使用phaser接口来与其他task对象同步。当这些任务正在执行他们的phases时候,主类运行3个任务并打印关于phaser对象的状态信息到操控台。 我们使用以下的方法来获取phaser对象的状态:
getphase():此方法返回phaser 任务的 actual phase
getregisteredparties(): 此方法返回使用phaser对象作为同步机制的任务数
getarrivedparties(): 此方法返回已经到达actual phase末端的任务数
getunarrivedparties(): 此方法返回还没到达actual phase末端的任务数
以下的裁图展示了项目的部分输出:

参见
<a href="http://ifeve.com/thread-synchronization-utilities-6-2/">第三章,线程同步应用:运行阶段性并发任务</a>