Java多線程與並發應用-(4)-傳統線程通訊技術試題

來源:互聯網
上載者:User

標籤:多線程   並發   java   安全執行緒   thread   

package com.lipeng;public class LoopDemo {/** * 線程A迴圈10次,然後線程B迴圈100次,然後A再迴圈10次,然後B再迴圈100次。如此迴圈50次。 * lipeng * 2015-4-10 * @param args */public static void main(String[] args) {MyTask task=new MyTask();RunA runA=new RunA(task);RunB runB=new RunB(task);new Thread(runA,"A").start();  //每個線程的start方法只能運行一次,但Run方法在不同的線程中可以運行多次。new Thread(runB,"B").start();}}

class RunA implements Runnable{private MyTask task;public RunA(MyTask task){this.task=task;}@Overridepublic void run() {try {for(int i=0;i<50;i++){task.A();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}


class RunB implements Runnable{private MyTask task;public  RunB(MyTask task){this.task=task;}@Overridepublic void run() {try {for(int i=0;i<50;i++){task.B();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

class MyTask{private boolean aGo=true;//切換開關,當true時A執行,false時B執行,執行完後切換條件public synchronized void A()throws Exception{while(!aGo)  //為何不用if???{//A 不能運行,等待this.wait();}for(int i=0;i<10;i++){System.out.println("AAAAA--------------"+i);}//運行完之後,將aGo切換為FALSE,讓B運行aGo=false;this.notify();//喚醒一個正在等待的線程 }public synchronized void B()throws Exception{while(aGo){//B 不能運行,等待this.wait();}for(int i=0;i<100;i++){System.out.println("B--------------"+i);}//運行完之後,將aGo切換為true,讓A運行aGo=true;this.notify();//喚醒一個正在等待的線程   }}


說明:

1. 如果有大於兩個多線程在執行,最好用notifyAll,為什嗎?

例如,如果本例中多起幾個線程,如果此時有A1,B1線程在wait,某個A線程執行完,將aGo置為false,並喚醒正在等待鎖的其中一個線程,A1或B1,如果此時正好A1線程搶到了CPU,則A1運行,判斷方法A1進入wait狀態,而B1由於沒有被喚醒,之後繼續等待,那麼到最後,A1和B1都處於wait狀態,造成了死結。

而如果改為notifyAll的話,A1和B1都被喚醒,搶到鎖的線程先執行,如果A1搶到的話,繼續等待,然後B1繼續執行,因為此時aGo=false,所以B1執行,將aGo=true,A1繼續執行完畢。

結論:只要A和B啟動的線程的個數不同,就可能造成死結的情況。

   2.判斷aGo的地方為什麼要使用while,if不行嗎?在wait方法說明中,也推薦使用while,因為在某些特定的情況下,線程有可能被假喚醒,使用while會迴圈檢測更穩妥。在本例中,A和B應該是交替啟動並執行,但是如果多啟動幾個線程,如果有A1線程在等待(wait)狀態,而A2線程執行完畢,aGo設定為false,喚醒正在等待的線程(可能是A也可能是B),如果是A被喚醒的話,如果用了if而不是while,那麼A執行,這樣A就連續執行了兩遍,不符合我們的設計要求,但如果換用while的話,即使A被喚醒,他會再次判斷aGo的值,發現是false,則繼續等待。直到B線程將其喚醒。

Java多線程與並發應用-(4)-傳統線程通訊技術試題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.