1. 程式人生 > >[one_demo_17]使用傳統方式實現執行緒間通訊的例子

[one_demo_17]使用傳統方式實現執行緒間通訊的例子

題目: 子執行緒迴圈10次,接著到主執行緒迴圈10次;接著又回到子執行緒迴圈10次,接著又到主執行緒迴圈10次,如此迴圈50次。

使用Object的wait()和notify()方法實現。

Java程式碼

第一種,不使用面向物件的思想實現

/**
 * 練習執行緒間通訊
 * 
 * @author Administrator
 *
 */
public class ThreadCommunicationOld {
	// 鎖
	private static String lock = "lock";

	// 執行緒間通訊的開關
	private static boolean isSub = true;

	public static void main(String[] args) {

		// 子執行緒
		new Thread(new Runnable() {
			public void run() {
				// 迴圈50次
				for (int i = 0; i < 50; i++) {
					// 加鎖
					synchronized (lock) {
						// 如果不是子執行緒狀態,就讓子執行緒阻塞
						if (!isSub) {
							try {
								lock.wait();
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
						// 執行任務10次
						for (int j = 0; j < 10; j++) {
							System.out.println("sub thread sequence of " + j + ", loop of " + i);
						}
						// 執行完任務後,調整為非子執行緒狀態
						isSub = false;
						// 喚醒主執行緒
						lock.notify();
					}
				}
			}
		}).start();

		// 主執行緒,執行50次
		for (int i = 0; i < 50; i++) {
			// 主執行緒加鎖
			synchronized (lock) {
				// 判斷是否為子執行緒狀態,如果是子執行緒狀態,就讓主執行緒阻塞
				if (isSub) {
					try {
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				// 執行任務10次
				for (int j = 0; j < 10; j++) {
					System.out.println("main thread sequence of " + j + ", loop of " + i);
				}
				// 調整為子執行緒狀態
				isSub = true;
				// 喚醒子執行緒
				lock.notify();
			}
		}
	}

}

第二種,使用面向物件的思想,將執行的業務放在一個業務類中,在這個業務類中,將執行的方法加上同步;另外,在判斷執行緒狀態時使用while取代if,防止出現假喚醒,也就是每次拿到鎖後,都要判斷狀態。

/**
 * 練習執行緒間通訊 題目: 子執行緒迴圈10次,接著到主執行緒迴圈100次;接著又回到子執行緒迴圈10次,接著又到主執行緒迴圈100次,如此迴圈50次
 * 
 * @author Administrator
 *
 */
public class ThreadCommunicationOld2 {

	public static void main(String[] args) {
		// 建立業務物件
		final Business business = new Business();
		// 子執行緒
		new Thread(new Runnable() {
			public void run() {
				// 迴圈50次
				for (int i = 0; i < 50; i++) {
					// 子執行緒業務
					business.sub(i);
				}
			}
		}).start();

		// 主執行緒,執行50次
		for (int i = 0; i < 50; i++) {
			// 主執行緒業務
			business.main(i);
		}

	}
}

// 將主執行緒或者子執行緒的業務交給業務類管理,更加的面向物件
class Business {
	// 執行緒狀態標識
	private boolean isSub = true;

	// 主執行緒業務
	public synchronized void main(int i) {
		// 判斷是否為子執行緒狀態,如果是子執行緒狀態,就讓主執行緒阻塞
		while (isSub) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		// 執行任務10次
		for (int j = 0; j < 10; j++) {
			System.out.println("main thread sequence of " + j + ", loop of " + i);
		}
		// 調整為子執行緒狀態
		isSub = true;
		// 喚醒子執行緒
		this.notify();
	}

	// 子執行緒業務
	public synchronized void sub(int i) {
		// 如果不是子執行緒狀態,就讓子執行緒阻塞
		while (!isSub) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		// 執行任務10次
		for (int j = 0; j < 10; j++) {
			System.out.println("sub thread sequence of " + j + ", loop of " + i);
		}
		// 執行完任務後,調整為非子執行緒狀態
		isSub = false;
		// 喚醒主執行緒
		this.notify();
	}
}