天天看點

測試并發應用(二)監控Phaser類

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&lt;</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&lt;</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末端的任務數

以下的裁圖展示了項目的部分輸出:

測試并發應用(二)監控Phaser類

參見

<a href="http://ifeve.com/thread-synchronization-utilities-6-2/">第三章,線程同步應用:運作階段性并發任務</a>

繼續閱讀