Java之多線程的數字加減案例(同步,等待與喚醒)


多線程控制數字的加減:

線程控制數字的加減過程應該是一個加一個減,這個和消費者模型有點像,加了后再減,加減不同同時進行,所以存在同步的問題。

/* 定義一個操作資源
*   這個類用來創建數值和加減切換開關還有加減的操作
*   其它線程類則創建這個類的屬性來進行關聯,並調用這個類中的方法實現加減的操作。
* */
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,加減法的交替進行得以驗證,但是因為線程優先級的問題,無法保證某一個方法的某個線程先執行。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM