線程的互斥與同步通信

synchronized的使用和wait與notify實現線程間的通信

案例: 子線程循環10次, 主線程循環5次, 兩者交替運行50次

代碼
package thread;

public class TraditionalThreadCommunication {
	public static void main(String[] args) {

		final Bussiness bussiness = new Bussiness();

		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 1; i <= 50; i++) {
					bussiness.sub(i);
				}
			}
		}).start();

		for (int i = 1; i <= 50; i++) {
			bussiness.main(i);
		}
	}
}

class Bussiness {
	private boolean flag = true;

	public synchronized void sub(int j) {
		// 如果flag爲false則等待
		while (!flag) {// 使用while 比較好 可以防止假喚醒
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for (int i = 1; i <= 10; i++) {
			System.out.println("sub : " + i + " 第" + j + "次外循環");
		}
		// 將flag置爲false 並喚醒主線程
		flag = false;
		this.notify();
	}

	public synchronized void main(int j) {
		// 如果flag爲true則等待
		while (flag) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for (int i = 1; i <= 5; i++) {
			System.out.println("main : " + i + " 第" + j + "次外循環");
		}
		// 將flag置爲true 並喚醒子線程
		flag = true;
		this.notify();
	}
}

將需要互斥的資源(屬性和方法) 統一定義在一個類中, 而不是將互斥代碼寫到線程中, 這樣做的好處是以後任何線程再訪問資源類的時候就可以保證是線程安全的

注意: 使用notify()和notifyAll()方法的時候是不會釋放鎖資源的


發佈了31 篇原創文章 · 獲贊 10 · 訪問量 9400
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章