多線程控制數字的加減:
線程控制數字的加減過程應該是一個加一個減,這個和消費者模型有點像,加了后再減,加減不同同時進行,所以存在同步的問題。
/* 定義一個操作資源 * 這個類用來創建數值和加減切換開關還有加減的操作 * 其它線程類則創建這個類的屬性來進行關聯,並調用這個類中的方法實現加減的操作。 * */ public class Resource { private int num = 0; // 進行加減操作的數據 private boolean flag =true; // 加減的切換 // flag = true : 表示可以進行加法操作,不能減法操作 // flag = false : 表示可以進行減法操作,不能加法操作 public synchronized void add(){ // 加法操作,已同步 if (this.flag == false){ // 現在需要執行的是減法操作,加法操作需要等待 try { super.wait(); // super 表示父類,wait()是Object的方法所以super指向的是Object } catch (InterruptedException e) { e.printStackTrace(); } } //延遲 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.num ++; System.out.println("【加法操作】- " + Thread.currentThread().getName() + ": num = " + this.num); // 因為flag = true執行加法,所以將flag設置為false執行減法 this.flag = false; // 加法操作執行完畢,需要進行減法操作 // super 表示父類,notifyAll()是Object的方法所以super指向的是Object super.notifyAll(); // 等待的可能是加法或者減法,那么就喚醒全部線程 } public synchronized void sub(){ // 減法操作,已同步 if (this.flag == true){ // 現在需要執行的是加法操作,減法操作需要等待 try { super.wait(); // super 表示父類,wait()是Object的方法所以super指向的是Object } catch (InterruptedException e) { e.printStackTrace(); } } //延遲 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.num --; System.out.println("【減法操作】- " + Thread.currentThread().getName() + ": num = " + this.num); this.flag = true; // true:執行加法 super.notifyAll(); // super 表示父類,notifyAll()是Object的方法所以super指向的是Object } }
// 加法線程 public class AddThread implements Runnable{ private Resource resource; public AddThread(Resource resource){ this.resource = resource; } @Override public void run() { for (int i = 0; i < 10; i++) { this.resource.add(); } } }
// 減法線程 public class SubThread implements Runnable{ private Resource resource; public SubThread(Resource resource){ this.resource = resource; } @Override public void run() { for (int i = 0; i < 10; i++) { this.resource.sub(); } } }
// 客戶端 public class Main { public static void main(String[] args) { Resource res = new Resource(); //創建資源類對象 AddThread at = new AddThread(res); //創建加法線程類對象 SubThread st = new SubThread(res); //創建減法線程類對象 new Thread(at,"加法線程 - A").start(); new Thread(at,"加法線程 - B").start(); new Thread(st,"減法線程 - A").start(); new Thread(st,"減法線程 - B").start(); } }
輸出結果:
num的值最終為0,加減法的交替進行得以驗證,但是因為線程優先級的問題,無法保證某一個方法的某個線程先執行。