【Java面試題】30 子線程循環10次,接着主線程循環100,接着又回到子線程循環10次,接着再回到主線程又循環100,如此循環50次,請寫出程序。


題目如下:

子線程循環10次,接着主線程循環100,接着又回到子線程循環10次, 接着再回到主線程又循環100,如此循環50次

 

思路如下:

子線程語主線程為互斥,可用SYNCHRONIZED。很容易想到如下代碼

package concurrent;  
  
public class theFirstIdea{  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
  
        new Thread(//子線程  
                new Runnable(){  
                    public void run(){  
                        for(int i=1;i<=50;i++){  
                            synchronized(theFirstIdea.class){  
                                for(int j=1;j<=10;j++){  
                                    System.out.println("sub thread: "+i+",loop: "+j);  
                                }  
                            }  
                        }  
                    }  
                }  
                ).start();  
  
        new Thread(//主線程  
                new Runnable(){  
                    public void run(){  
                        for(int i=1;i<=50;i++){  
                            synchronized(theFirstIdea.class){  
                                for(int j=1;j<=100;j++){  
                                    System.out.println("main thread: "+i+",loop: "+j);  
                                }  
                            }  
                        }  
                    }  
                }  
                ).start();  
    }  
  
}  

由於運行結果很長(有5500行),所以在Eclipse 編譯器無法全部看到,或看到的並不是最終運行結果。所以可以在Run -- Run configuration -- Common --勾選File,點擊File System.選擇到你想保存運行結果的地方,比如桌面,命名為1.txt. 此時桌面將會生產一個名為1.txt的文件,再次運行程序后,運行結果將保存到此文件中。便於查看。

 

  查看后發現,基本達到要求,但並沒有交替執行子線程和主線程。

  而且上述代碼不好,沒有體現Java 的高類聚性,最好能將共同數據或共同方法歸為同一類,即編寫一個類來存放兩個線程,便於修改。代碼如下

package concurrent;  
  
public class theFirstIdea{  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
  
        final MyThread threads=new MyThread();  
        new Thread(//子線程  
                new Runnable(){  
                    public void run(){  
                        for(int i=1;i<=50;i++){  
                            threads.subThread(i);  
                        }  
                    }  
                }     
                ).start();  
  
        for(int i=1;i<=50;i++){  
            threads.mainThread(i);  
        }  
    }  
}  
  
class MyThread{  
    public synchronized void subThread(int i){  
        for(int j=1;j<=10;j++){  
            System.out.println("sub thread: "+i+",loop: "+j);  
        }  
    }  
    public synchronized void mainThread(int i){  
        for(int j=1;j<=10;j++){  
            System.out.println("main thread: "+i+",loop: "+j);  
        }  
    }  
}  

要讓他們交替進行,可用信號量控制,並用wait  ,notify 進行線程間通信。易得

//子線程循環10次,接着主線程循環100,接着又回到子線程循環10次,  
//接着再回到主線程又循環100,如此循環50次,請寫出程序。  
  
public class ThreadTest{  
  
  
    public static void main(String[] args) {  
  
        final MyThread threads=new MyThread();  
        new Thread(  
                new Runnable(){  
                    public void run(){  
                        for(int i=1;i<=50;i++){  
                            threads.subThread(i);  
                        }  
                    }  
                }  
                ).start();  
        new Thread(new Runnable(){  
            public void run(){  
                for(int i=1;i<=50;i++){  
                    threads.mainThread(i);  
                }  
            }  
        }).start();  
    }  
}  
  
class MyThread{  
    boolean bShouldSub=true;//標志子線程方法是否被調用  
    public synchronized void subThread(int i){  
        if(!bShouldSub){//若子線程沒被調用,即主線程正在運行,所以等待  
            try {  
                this.wait();  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
        for(int j=1;j<=10;j++){  
            System.out.println("sub thread :"+i+",loop : "+j);  
        }  
        bShouldSub=false;//子線程運行完畢  
        this.notify();//喚醒其他線程,即主線程  
    }  
    public synchronized void mainThread(int i){  
        if(bShouldSub){//若子線程正在被調用,所以等待  
            try {  
                this.wait();  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
        for(int j=1;j<=100;j++){  
            System.out.println("main thread :"+i+",loop : "+j);  
        }  
        bShouldSub=true;//主線程調用完畢  
        this.notify();//喚醒子線程  
    }  
}  

轉自:http://blog.csdn.net/carlosli/article/details/8738960

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM