[one_demo_17]使用傳統方式實現執行緒間通訊的例子
阿新 • • 發佈:2018-12-02
題目: 子執行緒迴圈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(); } }