Java多線程面試題:子線程循環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();//喚醒子線程
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章