天天看點

并發工具類(四)兩個線程進行資料交換的Exchanger

exchanger(交換者)是一個用于線程間協作的工具類。exchanger用于進行線程間的資料交換。它提供一個同步點,在這個同步點兩個線程可以交換彼此的資料。這兩個線程通過exchange方法交換資料, 如果第一個線程先執行exchange方法,它會一直等待第二個線程也執行exchange,當兩個線程都到達同步點時,這兩個線程就可以交換資料,将本線程生産出來的資料傳遞給對方。

exchanger可以用于遺傳算法,遺傳算法裡需要選出兩個人作為交配對象,這時候會交換兩人的資料,并使用交叉規則得出2個交配結果。

exchanger也可以用于校對工作。比如我們需要将紙制銀流通過人工的方式錄入成電子銀行流水,為了避免錯誤,采用ab崗兩人進行錄入,錄入到excel之後,系統需要加載這兩個excel,并對這兩個excel資料進行校對,看看是否錄入的一緻。代碼如下:

<code>01</code>

<code>public</code> <code>class</code> <code>exchangertest {</code>

<code>02</code>

<code>03</code>

<code>    </code><code>private</code> <code>static</code> <code>final</code> <code>exchanger&lt;string&gt; exgr = </code><code>new</code> <code>exchanger&lt;string&gt;();</code>

<code>04</code>

<code>05</code>

<code>    </code><code>private</code> <code>static</code> <code>executorservice threadpool = executors.newfixedthreadpool(</code><code>2</code><code>);</code>

<code>06</code>

<code>07</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>

<code>08</code>

<code>09</code>

<code>        </code><code>threadpool.execute(</code><code>new</code> <code>runnable() {</code>

<code>10</code>

<code>            </code><code>@override</code>

<code>11</code>

<code>            </code><code>public</code> <code>void</code> <code>run() {</code>

<code>12</code>

<code>                </code><code>try</code> <code>{</code>

<code>13</code>

<code>                    </code><code>string a = </code><code>"銀行流水a"</code><code>;</code><code>// a錄入銀行流水資料</code>

<code>14</code>

<code>                    </code><code>exgr.exchange(a);</code>

<code>15</code>

<code>                </code><code>} </code><code>catch</code> <code>(interruptedexception e) {</code>

<code>16</code>

<code>                </code><code>}</code>

<code>17</code>

<code>            </code><code>}</code>

<code>18</code>

<code>        </code><code>});</code>

<code>19</code>

<code>20</code>

<code>21</code>

<code>22</code>

<code>23</code>

<code>24</code>

<code>                    </code><code>string b = </code><code>"銀行流水b"</code><code>;</code><code>// b錄入銀行流水資料</code>

<code>25</code>

<code>                    </code><code>string a = exgr.exchange(</code><code>"b"</code><code>);</code>

<code>26</code>

<code>                    </code><code>system.out.println(</code><code>"a和b資料是否一緻:"</code> <code>+ a.equals(b) + </code><code>",a錄入的是:"</code>

<code>27</code>

<code>                            </code><code>+ a + </code><code>",b錄入是:"</code> <code>+ b);</code>

<code>28</code>

<code>29</code>

<code>30</code>

<code>31</code>

<code>32</code>

<code>33</code>

<code>        </code><code>threadpool.shutdown();</code>

<code>34</code>

<code>35</code>

<code>    </code><code>}</code>

<code>36</code>

<code>}</code>

如果兩個線程有一個沒有到達exchange方法,則會一直等待,如果擔心有特殊情況發生,避免一直等待,可以使用exchange(v x, long timeout, timeunit unit)設定最大等待時長。