題目如下:
子線程循環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
