多線程_線程同步小程序


1:需求:子線程執行10次,主線程執行100次,再子線程10次,主線程100次,如此的往復50次。 

2爲了方便看結果,先把次數改成10次,10次,10次。 

3總結:

  互斥:同一塊代碼的原子性操作,不容其它代碼打亂 

  同步:不同代碼塊之間,在互斥的基礎上,按照順序執行 對於互斥和同步的代碼塊,應該使用業務類來處理,要獨立於線程類,再讓線程類來調用業務類,實現需求。

代碼:

public class TraditionalThreadCommunication {

	public static void main(String[] args) {
       final Business business=new Business();
       
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					business.sub(i);
				}

			}
		}).start();
		
		for (int i = 0; i < 10; i++) {
			business.main(i);
		}

	}

}

/*
 * 更面向對象:將線程執行的任務邏輯放到一個業務類裏面,<br> 
 * 在業務類中控制他們的互斥和同步<br>
 *  ①使用synchronized進行互斥,說到底就是同一代碼的原子性,不可再分。<br>
 *  ②使用一個變量bShouldSub進行同步,說到底就是不同代碼的執行順序。<br>
 */
class Business {
	boolean bShouldSub = true;

	public synchronized void sub(int i) {
		//當代碼進來後,線程發現不該自己運行(逆向思維),於是等待,並喚醒其他線程
		/*
		 * 有時候線程是僞喚醒:即其他線程還在執行,這個線程就醒了,也要執行,就會
		 *  打亂其他線程的執行。這時,要繼續判斷一下這個線程是否滿足執行條件,使用while即可。
		 */
		while (!bShouldSub) {
			try {
				this.wait(); //線程等待:即代碼中斷
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
        //當該自己走,走完後,將bShuouldSub置false,並喚醒其他線程
		for (int j = 0; j < 10; j++) {
			System.out.println("sub thread sequence of " + j + ",loop of" + i);
		}
		bShouldSub=false;
		this.notify();//由於另一個線程可能進入了wait,需要喚醒
		

	}

	public synchronized void main(int i) {
		//當代碼進來後,線程發現不該自己運行(逆向思維),於是等待,並喚醒其他線程
		while (bShouldSub) { 
			try {
				this.wait(); //線程等待:即代碼中斷
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//當該自己走,走完後,將bShuouldSub置true,並喚醒其他線程
		for (int j = 0; j < 10; j++) {
			System.out.println("main thread sequence of " + j + ",loop of" + i);
		}
		bShouldSub=true;
		this.notify();//由於另一個線程可能進入了wait,需要喚醒
	}
}


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