天天看點

java 線程

<a href="http://lavasoft.blog.51cto.com/62575/27069/">http://lavasoft.blog.51cto.com/62575/27069/</a>

在java中要想實作多線程,有兩種手段,一種是繼續Thread類,另外一種是實作Runable接口。

對于直接繼承Thread的類來說,代碼大緻架構是:

<a href="http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html">?</a>

<code>class</code> <code>類名</code><code>extends</code> <code>Thread{</code>

<code>方法</code><code>1</code><code>;</code>

<code>方法</code><code>2</code><code>;</code>

<code>…</code>

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

<code>// other code…</code>

<code>}</code>

<code>屬性</code><code>1</code><code>;</code>

<code>屬性</code><code>2</code><code>;</code>

先看一個簡單的例子:

<code>/**</code>

<code> </code><code>* @author Rollen-Holt 繼承Thread類,直接調用run方法</code>

<code> </code><code>* */</code>

<code>class</code> <code>hello</code><code>extends</code> <code>Thread {</code>

<code>    </code><code>public</code> <code>hello() {</code>

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

<code>    </code><code>public</code> <code>hello(String name) {</code>

<code>        </code><code>this</code><code>.name = name;</code>

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

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i =</code><code>0</code><code>; i &lt;</code><code>5</code><code>; i++) {</code>

<code>            </code><code>System.out.println(name +</code><code>"運作     "</code> <code>+ i);</code>

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

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

<code>        </code><code>hello h1=</code><code>new</code> <code>hello(</code><code>"A"</code><code>);</code>

<code>        </code><code>hello h2=</code><code>new</code> <code>hello(</code><code>"B"</code><code>);</code>

<code>        </code><code>h1.run();</code>

<code>        </code><code>h2.run();</code>

<code>    </code><code>private</code> <code>String name;</code>

【運作結果】:

A運作     0

A運作     1

A運作     2

A運作     3

A運作     4

B運作     0

B運作     1

B運作     2

B運作     3

B運作     4

我們會發現這些都是順序執行的,說明我們的調用方法不對,應該調用的是start()方法。

當我們把上面的主函數修改為如下所示的時候:

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

<code>        </code><code>h1.start();</code>

<code>        </code><code>h2.start();</code>

然後運作程式,輸出的可能的結果如下:

因為需要用到CPU的資源,是以每次的運作結果基本是都不一樣的,呵呵。

注意:雖然我們在這裡調用的是start()方法,但是實際上調用的還是run()方法的主體。

那麼:為什麼我們不能直接調用run()方法呢?

我的了解是:線程的運作需要本地作業系統的支援。

如果你檢視start的源代碼的時候,會發現:

<code>public</code> <code>synchronized</code> <code>void</code> <code>start() {</code>

<code>        </code><code>/**</code>

<code>     </code><code>* This method is not invoked for the main method thread or "system"</code>

<code>     </code><code>* group threads created/set up by the VM. Any new functionality added</code>

<code>     </code><code>* to this method in the future may have to also be added to the VM.</code>

<code>     </code><code>*</code>

<code>     </code><code>* A zero status value corresponds to state "NEW".</code>

<code>         </code><code>*/</code>

<code>        </code><code>if</code> <code>(threadStatus !=</code><code>0</code> <code>||</code><code>this</code> <code>!= me)</code>

<code>            </code><code>throw</code> <code>new</code> <code>IllegalThreadStateException();</code>

<code>        </code><code>group.add(</code><code>this</code><code>);</code>

<code>        </code><code>start0();</code>

<code>        </code><code>if</code> <code>(stopBeforeStart) {</code>

<code>        </code><code>stop0(throwableFromStop);</code>

<code>private</code> <code>native</code> <code>void</code> <code>start0();</code>

注意我用紅色加粗的那一條語句,說明此處調用的是start0()。并且這個這個方法用了native關鍵字,次關鍵字表示調用本地作業系統的函數。因為多線程的實作需要本地作業系統的支援。

但是start方法重複調用的話,會出現java.lang.IllegalThreadStateException異常。

通過實作Runnable接口:

大緻架構是:

<code>class</code> <code>類名</code><code>implements</code> <code>Runnable{</code>

來先看一個小例子吧:

<code> </code><code>* @author Rollen-Holt 實作Runnable接口</code>

<code>class</code> <code>hello</code><code>implements</code> <code>Runnable {</code>

<code>        </code><code>hello h1=</code><code>new</code> <code>hello(</code><code>"線程A"</code><code>);</code>

<code>        </code><code>Thread demo=</code><code>new</code> <code>Thread(h1);</code>

<code>        </code><code>hello h2=</code><code>new</code> <code>hello(</code><code>"線程B"</code><code>);</code>

<code>        </code><code>Thread demo1=</code><code>new</code> <code>Thread(h2);</code>

<code>        </code><code>demo.start();</code>

<code>        </code><code>demo1.start();</code>

【可能的運作結果】:

線程A運作     0

線程B運作     0

線程B運作     1

線程B運作     2

線程B運作     3

線程B運作     4

線程A運作     1

線程A運作     2

線程A運作     3

線程A運作     4

關于選擇繼承Thread還是實作Runnable接口?

其實Thread也是實作Runnable接口的:

<code>class</code> <code>Thread</code><code>implements</code> <code>Runnable {</code>

<code>    </code><code>//…</code>

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

<code>        </code><code>if</code> <code>(target !=</code><code>null</code><code>) {</code>

<code>             </code><code>target.run();</code>

Thread和Runnable的差別:

如果一個類繼承Thread,則不适合資源共享。但是如果實作了Runable接口的話,則很容易的實作資源共享。

<code> </code><code>* @author Rollen-Holt 繼承Thread類,不能資源共享</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i =</code><code>0</code><code>; i &lt;</code><code>7</code><code>; i++) {</code>

<code>            </code><code>if</code> <code>(count &gt;</code><code>0</code><code>) {</code>

<code>                </code><code>System.out.println(</code><code>"count= "</code> <code>+ count--);</code>

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

<code>        </code><code>hello h1 =</code><code>new</code> <code>hello();</code>

<code>        </code><code>hello h2 =</code><code>new</code> <code>hello();</code>

<code>        </code><code>hello h3 =</code><code>new</code> <code>hello();</code>

<code>        </code><code>h3.start();</code>

<code>    </code><code>private</code> <code>int</code> <code>count =</code><code>5</code><code>;</code>

count= 5

count= 4

count= 3

count= 2

count= 1

大家可以想象,如果這個是一個買票系統的話,如果count表示的是車票的數量的話,說明并沒有實作資源的共享。

我們換為Runnable接口:

<code>        </code><code>hello he=</code><code>new</code> <code>hello();</code>

<code>        </code><code>new</code> <code>Thread(he).start();</code>

總結一下吧:

實作Runnable接口比繼承Thread類所具有的優勢:

1):适合多個相同的程式代碼的線程去處理同一個資源

2):可以避免java中的單繼承的限制

3):增加程式的健壯性,代碼可以被多個線程共享,代碼和資料獨立。

是以,本人建議大家勁量實作接口。

<code> </code><code>* @author Rollen-Holt</code>

<code> </code><code>* 取得線程的名稱</code>

<code>        </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>            </code><code>System.out.println(Thread.currentThread().getName());</code>

<code>        </code><code>hello he =</code><code>new</code> <code>hello();</code>

<code>        </code><code>new</code> <code>Thread(he,</code><code>"A"</code><code>).start();</code>

<code>        </code><code>new</code> <code>Thread(he,</code><code>"B"</code><code>).start();</code>

A

B

Thread-0

說明如果我們沒有指定名字的話,系統自動提供名字。

提醒一下大家:main方法其實也是一個線程。在java中是以的線程都是同時啟動的,至于什麼時候,哪個先執行,完全看誰先得到CPU的資源。

在java中,每次程式運作至少啟動2個線程。一個是main線程,一個是垃圾收集線程。因為每當使用java指令執行一個類的時候,實際上都會啟動一個JVM,每一個jVM實習在就是在作業系統中啟動了一個程序。

判斷線程是否啟動

<code> </code><code>* @author Rollen-Holt 判斷線程是否啟動</code>

<code>        </code><code>Thread demo =</code><code>new</code> <code>Thread(he);</code>

<code>        </code><code>System.out.println(</code><code>"線程啟動之前---》"</code> <code>+ demo.isAlive());</code>

<code>        </code><code>System.out.println(</code><code>"線程啟動之後---》"</code> <code>+ demo.isAlive());</code>

【運作結果】

線程啟動之前---》false

線程啟動之後---》true

主線程也有可能在子線程結束之前結束。并且子線程不受影響,不會因為主線程的結束而結束。

線程的強制執行:

<code>     </code><code>* @author Rollen-Holt 線程的強制執行</code>

<code>     </code><code>* */</code>

<code>    </code><code>class</code> <code>hello</code><code>implements</code> <code>Runnable {</code>

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

<code>            </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>                </code><code>System.out.println(Thread.currentThread().getName());</code>

<code>    </code> 

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

<code>            </code><code>hello he =</code><code>new</code> <code>hello();</code>

<code>            </code><code>Thread demo =</code><code>new</code> <code>Thread(he,</code><code>"線程"</code><code>);</code>

<code>            </code><code>demo.start();</code>

<code>            </code><code>for</code><code>(</code><code>int</code> <code>i=</code><code>0</code><code>;i&lt;</code><code>50</code><code>;++i){</code>

<code>                </code><code>if</code><code>(i&gt;</code><code>10</code><code>){</code>

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

<code>                        </code><code>demo.join(); </code><code>//強制執行demo</code>

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

<code>                        </code><code>e.printStackTrace();</code>

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

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

<code>                </code><code>System.out.println(</code><code>"main 線程執行--&gt;"</code><code>+i);</code>

【運作的結果】:

main 線程執行--&gt;0

main 線程執行--&gt;1

main 線程執行--&gt;2

main 線程執行--&gt;3

main 線程執行--&gt;4

main 線程執行--&gt;5

main 線程執行--&gt;6

main 線程執行--&gt;7

main 線程執行--&gt;8

main 線程執行--&gt;9

main 線程執行--&gt;10

線程

main 線程執行--&gt;11

main 線程執行--&gt;12

main 線程執行--&gt;13

...

線程的休眠:

<code> </code><code>* @author Rollen-Holt 線程的休眠</code>

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

<code>                </code><code>Thread.sleep(</code><code>2000</code><code>);</code>

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

<code>                </code><code>e.printStackTrace();</code>

<code>            </code><code>System.out.println(Thread.currentThread().getName() + i);</code>

<code>        </code><code>Thread demo =</code><code>new</code> <code>Thread(he,</code><code>"線程"</code><code>);</code>

【運作結果】:(結果每隔2s輸出一個)

線程0

線程1

線程2

線程的中斷:

<code> </code><code>* @author Rollen-Holt 線程的中斷</code>

<code>        </code><code>System.out.println(</code><code>"執行run方法"</code><code>);</code>

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

<code>            </code><code>Thread.sleep(</code><code>10000</code><code>);</code>

<code>            </code><code>System.out.println(</code><code>"線程完成休眠"</code><code>);</code>

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

<code>            </code><code>System.out.println(</code><code>"休眠被打斷"</code><code>);</code>

<code>            </code><code>return</code><code>; </code><code>//傳回到程式的調用處</code>

<code>        </code><code>System.out.println(</code><code>"線程正常終止"</code><code>);</code>

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

<code>            </code><code>Thread.sleep(</code><code>2000</code><code>);</code>

<code>            </code><code>e.printStackTrace();</code>

<code>        </code><code>demo.interrupt();</code><code>//2s後中斷線程</code>

執行run方法

休眠被打斷

在java程式中,隻要前台有一個線程在運作,整個java程式程序不會小時,是以此時可以設定一個背景線程,這樣即使java程序小時了,此背景線程依然能夠繼續運作。

<code> </code><code>* @author Rollen-Holt 背景線程</code>

<code>        </code><code>while</code> <code>(</code><code>true</code><code>) {</code>

<code>            </code><code>System.out.println(Thread.currentThread().getName() +</code><code>"在運作"</code><code>);</code>

<code>        </code><code>demo.setDaemon(</code><code>true</code><code>);</code>

雖然有一個死循環,但是程式還是可以執行完的。因為在死循環中的線程操作已經設定為背景運作了。

線程的優先級:

<code> </code><code>* @author Rollen-Holt 線程的優先級</code>

<code>        </code><code>for</code><code>(</code><code>int</code> <code>i=</code><code>0</code><code>;i&lt;</code><code>5</code><code>;++i){</code>

<code>            </code><code>System.out.println(Thread.currentThread().getName()+</code><code>"運作"</code><code>+i);</code>

<code>        </code><code>Thread h1=</code><code>new</code> <code>Thread(</code><code>new</code> <code>hello(),</code><code>"A"</code><code>);</code>

<code>        </code><code>Thread h2=</code><code>new</code> <code>Thread(</code><code>new</code> <code>hello(),</code><code>"B"</code><code>);</code>

<code>        </code><code>Thread h3=</code><code>new</code> <code>Thread(</code><code>new</code> <code>hello(),</code><code>"C"</code><code>);</code>

<code>        </code><code>h1.setPriority(</code><code>8</code><code>);</code>

<code>        </code><code>h2.setPriority(</code><code>2</code><code>);</code>

<code>        </code><code>h3.setPriority(</code><code>6</code><code>);</code>

<code>        </code> 

A運作0

A運作1

A運作2

A運作3

A運作4

B運作0

C運作0

C運作1

C運作2

C運作3

C運作4

B運作1

B運作2

B運作3

B運作4

。但是請讀者不要誤以為優先級越高就先執行。誰先執行還是取決于誰先去的CPU的資源、

另外,主線程的優先級是5.

線程的禮讓。

線上程操作中,也可以使用yield()方法,将一個線程的操作暫時交給其他線程執行。

<code>            </code><code>if</code><code>(i==</code><code>3</code><code>){</code>

<code>                </code><code>System.out.println(</code><code>"線程的禮讓"</code><code>);</code>

<code>                </code><code>Thread.currentThread().yield();</code>

線程的禮讓

同步和死鎖:

【問題引出】:比如說對于買票系統,有下面的代碼:

<code>        </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>            </code><code>if</code><code>(count&gt;</code><code>0</code><code>){</code>

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

<code>                    </code><code>Thread.sleep(</code><code>1000</code><code>);</code>

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

<code>                    </code><code>e.printStackTrace();</code>

<code>                </code><code>System.out.println(count--);</code>

<code>        </code><code>Thread h1=</code><code>new</code> <code>Thread(he);</code>

<code>        </code><code>Thread h2=</code><code>new</code> <code>Thread(he);</code>

<code>        </code><code>Thread h3=</code><code>new</code> <code>Thread(he);</code>

<code>    </code><code>private</code> <code>int</code> <code>count=</code><code>5</code><code>;</code>

5

4

3

2

1

-1

這裡出現了-1,顯然這個是錯的。,應該票數不能為負值。

如果想解決這種問題,就需要使用同步。所謂同步就是在統一時間段中隻有有一個線程運作,

其他的線程必須等到這個線程結束之後才能繼續執行。

【使用線程同步解決問題】

采用同步的話,可以使用同步代碼塊和同步方法兩種來完成。

【同步代碼塊】:

文法格式:

synchronized(同步對象){

 //需要同步的代碼

}

但是一般都把目前對象this作為同步對象。

比如對于上面的買票的問題,如下:

<code>            </code><code>synchronized</code> <code>(</code><code>this</code><code>) {</code>

<code>                </code><code>if</code><code>(count&gt;</code><code>0</code><code>){</code>

<code>                        </code><code>Thread.sleep(</code><code>1000</code><code>);</code>

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

<code>                    </code><code>System.out.println(count--);</code>

【運作結果】:(每一秒輸出一個結果)

【同步方法】

也可以采用同步方法。

文法格式為synchronized 方法傳回類型 方法名(參數清單){

    // 其他代碼

現在,我們采用同步方法解決上面的問題。

<code>        </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>            </code><code>sale();</code>

<code>    </code><code>public</code> <code>synchronized</code> <code>void</code> <code>sale() {</code>

<code>        </code><code>if</code> <code>(count &gt;</code><code>0</code><code>) {</code>

<code>                </code><code>Thread.sleep(</code><code>1000</code><code>);</code>

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

<code>            </code><code>System.out.println(count--);</code>

<code>        </code><code>Thread h1 =</code><code>new</code> <code>Thread(he);</code>

<code>        </code><code>Thread h2 =</code><code>new</code> <code>Thread(he);</code>

<code>        </code><code>Thread h3 =</code><code>new</code> <code>Thread(he);</code>

【運作結果】(每秒輸出一個)

提醒一下,當多個線程共享一個資源的時候需要進行同步,但是過多的同步可能導緻死鎖。

此處列舉經典的生産者和消費者問題。

【生産者和消費者問題】

先看一段有問題的代碼。

<code>class</code> <code>Info {</code>

<code>    </code><code>public</code> <code>String getName() {</code>

<code>        </code><code>return</code> <code>name;</code>

<code>    </code><code>public</code> <code>void</code> <code>setName(String name) {</code>

<code>    </code><code>public</code> <code>int</code> <code>getAge() {</code>

<code>        </code><code>return</code> <code>age;</code>

<code>    </code><code>public</code> <code>void</code> <code>setAge(</code><code>int</code> <code>age) {</code>

<code>        </code><code>this</code><code>.age = age;</code>

<code>    </code><code>private</code> <code>String name =</code><code>"Rollen"</code><code>;</code>

<code>    </code><code>private</code> <code>int</code> <code>age =</code><code>20</code><code>;</code>

<code> </code><code>* 生産者</code>

<code>class</code> <code>Producer</code><code>implements</code> <code>Runnable{</code>

<code>    </code><code>private</code> <code>Info info=</code><code>null</code><code>;</code>

<code>    </code><code>Producer(Info info){</code>

<code>        </code><code>this</code><code>.info=info;</code>

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

<code>        </code><code>boolean</code> <code>flag=</code><code>false</code><code>;</code>

<code>        </code><code>for</code><code>(</code><code>int</code> <code>i=</code><code>0</code><code>;i&lt;</code><code>25</code><code>;++i){</code>

<code>            </code><code>if</code><code>(flag){</code>

<code>                </code><code>this</code><code>.info.setName(</code><code>"Rollen"</code><code>);</code>

<code>                    </code><code>Thread.sleep(</code><code>100</code><code>);</code>

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

<code>                </code><code>this</code><code>.info.setAge(</code><code>20</code><code>);</code>

<code>                </code><code>flag=</code><code>false</code><code>;</code>

<code>            </code><code>}</code><code>else</code><code>{</code>

<code>                </code><code>this</code><code>.info.setName(</code><code>"chunGe"</code><code>);</code>

<code>                </code><code>this</code><code>.info.setAge(</code><code>100</code><code>);</code>

<code>                </code><code>flag=</code><code>true</code><code>;</code>

<code> </code><code>* 消費者類</code>

<code>class</code> <code>Consumer</code><code>implements</code> <code>Runnable{</code>

<code>    </code><code>public</code> <code>Consumer(Info info){</code>

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

<code>                </code><code>Thread.sleep(</code><code>100</code><code>);</code>

<code>            </code><code>System.out.println(</code><code>this</code><code>.info.getName()+</code><code>"&lt;----&gt;"</code><code>+</code><code>this</code><code>.info.getAge());</code>

<code> </code><code>* 測試類</code>

<code>class</code> <code>hello{</code>

<code>        </code><code>Info info=</code><code>new</code> <code>Info();</code>

<code>        </code><code>Producer pro=</code><code>new</code> <code>Producer(info);</code>

<code>        </code><code>Consumer con=</code><code>new</code> <code>Consumer(info);</code>

<code>        </code><code>new</code> <code>Thread(pro).start();</code>

<code>        </code><code>new</code> <code>Thread(con).start();</code>

Rollen&lt;----&gt;100

chunGe&lt;----&gt;20

chunGe&lt;----&gt;100

大家可以從結果中看到,名字和年齡并沒有對于。

那麼如何解決呢?

1) 加入同步

2) 加入等待和喚醒

先來看看加入同步會是如何。

<code>    </code><code>public</code> <code>synchronized</code> <code>void</code> <code>set(String name,</code><code>int</code> <code>age){</code>

<code>        </code><code>this</code><code>.name=name;</code>

<code>            </code><code>Thread.sleep(</code><code>100</code><code>);</code>

<code>        </code><code>this</code><code>.age=age;</code>

<code>    </code><code>public</code> <code>synchronized</code> <code>void</code> <code>get(){</code>

<code>        </code><code>System.out.println(</code><code>this</code><code>.getName()+</code><code>"&lt;===&gt;"</code><code>+</code><code>this</code><code>.getAge());</code>

<code>class</code> <code>Producer</code><code>implements</code> <code>Runnable {</code>

<code>    </code><code>private</code> <code>Info info =</code><code>null</code><code>;</code>

<code>    </code><code>Producer(Info info) {</code>

<code>        </code><code>this</code><code>.info = info;</code>

<code>        </code><code>boolean</code> <code>flag =</code><code>false</code><code>;</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i =</code><code>0</code><code>; i &lt;</code><code>25</code><code>; ++i) {</code>

<code>            </code><code>if</code> <code>(flag) {</code>

<code>                </code> 

<code>                </code><code>this</code><code>.info.set(</code><code>"Rollen"</code><code>,</code><code>20</code><code>);</code>

<code>                </code><code>flag =</code><code>false</code><code>;</code>

<code>            </code><code>}</code><code>else</code> <code>{</code>

<code>                </code><code>this</code><code>.info.set(</code><code>"ChunGe"</code><code>,</code><code>100</code><code>);</code>

<code>                </code><code>flag =</code><code>true</code><code>;</code>

<code>class</code> <code>Consumer</code><code>implements</code> <code>Runnable {</code>

<code>    </code><code>public</code> <code>Consumer(Info info) {</code>

<code>            </code><code>this</code><code>.info.get();</code>

<code>class</code> <code>hello {</code>

<code>        </code><code>Info info =</code><code>new</code> <code>Info();</code>

<code>        </code><code>Producer pro =</code><code>new</code> <code>Producer(info);</code>

<code>        </code><code>Consumer con =</code><code>new</code> <code>Consumer(info);</code>

Rollen&lt;===&gt;20

ChunGe&lt;===&gt;100

從運作結果來看,錯亂的問題解決了,現在是Rollen 對應20,ChunGe對于100

,但是還是出現了重複讀取的問題,也肯定有重複覆寫的問題。如果想解決這個問題,就需要使用Object類幫忙了、

,我們可以使用其中的等待和喚醒操作。

要完成上面的功能,我們隻需要修改Info類饑渴,在其中加上标志位,并且通過判斷标志位完成等待和喚醒的操作,代碼如下:

<code>        </code><code>if</code><code>(!flag){</code>

<code>                </code><code>super</code><code>.wait();</code>

<code>        </code><code>flag=</code><code>false</code><code>;</code>

<code>        </code><code>super</code><code>.notify();</code>

<code>        </code><code>if</code><code>(flag){</code>

<code>        </code><code>flag=</code><code>true</code><code>;</code>

<code>    </code><code>private</code> <code>boolean</code> <code>flag=</code><code>false</code><code>;</code>

<code>【程式運作結果】:</code>

<code>Rollen&lt;===&gt;</code><code>20</code>

<code>ChunGe&lt;===&gt;</code><code>100</code>

<code>先在看結果就可以知道,之前的問題完全解決。</code>

《完》