多線程范圍內的數據共享


多線程范圍內的共享解決方法參考有4中:

1.如果線程執行的代碼相同,多個線程共享同一個runnable對象時,將共享數據放在runnable對象

2.如果多個線程執行的代碼不同,將共享數據封裝到一個對象中,將這個對象逐一傳遞給各個runnable對象

3.如果多個線程執行的代碼不同,將共享數據作為外部類的final成員變量,將不同的runnable對象作為內部類主動取數據

4.將數據聲明為static的方式()

見如下示例:

1.如果線程執行的代碼相同,多個線程共享同一個runnable對象時,將共享數據放在runnable對象

public class MuiltThreadShare {
    /**
     * 多個線程共享數據方法:
     * 1.如果線程執行的代碼相同,多個線程共享同一個runnable對象時,將共享數據放在runnable對象
     * 2.如果多個線程執行的代碼不同,將共享數據封裝到一個對象中,將這個對象逐一傳遞給各個runnable對象
     * 3.如果多個線程執行的代碼不同,將共享數據作為外部類的final成員變量,將不同的runnable對象作為內部類主動取數據
     */
    
    public static void main(String[] args) {
        //1.方式一
        Task1 task1 = new Task1();
        new Thread(task1).start();
        new Thread(task1).start();
        new Thread(task1).start();
        
        
        
    }
    

}

class Task1 implements Runnable{
    /**
     * 1.如果線程執行的代碼相同,多個線程共享同一個runnable對象時,將共享數據放在runnable對象
     */
    
    private int i = 100;

    @Override
    public void run() {
        increase();
        decrease();
    }
    
    private synchronized void increase(){
        try {
            Thread.sleep(200);//為了更容易看到線程執行現象
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        i++;
        System.out.println(Thread.currentThread().getName() +",num:"+i);
    }
    private synchronized void decrease(){
        i--;
        System.out.println(Thread.currentThread().getName() +",num:"+i);
    }

運行結果:最終還是100,不同的線程使用共享數據

運行結果
//    Thread-0,num:101
//    Thread-2,num:102
//    Thread-1,num:103
//    Thread-2,num:102
//    Thread-0,num:101
//    Thread-1,num:100

 

2.如果多個線程執行的代碼不同,將共享數據封裝到一個對象中,將這個對象逐一傳遞給各個runnable對象

 

public class MuiltThreadDataShare2 {
    public static void main(String[] args) {
        // 2.如果多個線程執行的代碼不同,將共享數據封裝到一個對象中,將這個對象逐一傳遞給各個runnable對象
        /**
         * 模擬銀行轉賬功能,可以指定存取款金額,賬號初始額度100
         */
        ShareData data = new ShareData(0);

        // 存50元
        new Thread(new TaskIncrease(data, 50)).start();
        // 取30元
        new Thread(new Taskdecrease(data, 30)).start();
        // 存20
        new Thread(new TaskIncrease(data, 20)).start();

    }

}

class Taskdecrease implements Runnable {
    public Taskdecrease(ShareData shareData, int num) {
        this.shareData = shareData;
        this.num = num;
    }

    private int num;

    private ShareData shareData;

    @Override
    public void run() {
        shareData.decrease(num);
    }

}

class TaskIncrease implements Runnable {
    public TaskIncrease(ShareData shareData, int num) {
        this.shareData = shareData;
        this.num = num;
    }

    private ShareData shareData;
    private int num;

    @Override
    public void run() {
        shareData.increase(num);
    }

}

class ShareData {
    public ShareData(int num) {
        i = num;
        System.out.println("賬戶進行初始化,金額為:" + num);
    }

    private int i;

    public synchronized void increase(int i) {
        try {
            Thread.sleep(200);// 為了更容易看到線程執行現象
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.i = this.i + i;
        System.out.println(Thread.currentThread().getName() + "賬戶存入" + i + "元,目前賬戶余額為:" + this.i);
    }

    public synchronized void decrease(int i) {
        this.i = this.i - i;
        System.out.println(Thread.currentThread().getName() + "賬戶取出" + i + "元,目前賬戶余額為:" + this.i);
    }
}

運行結果:

賬戶進行初始化,金額為:0
Thread-0賬戶存入50元,目前賬戶余額為:50
Thread-2賬戶存入20元,目前賬戶余額為:70
Thread-1賬戶取出30元,目前賬戶余額為:40

 

3.如果多個線程執行的代碼不同,將共享數據作為外部類的final成員變量,將不同的runnable對象作為內部類主動取數據

 

public class MuiltThreadDataShare3 {


    public static void main(String[] args) {
        final Data data = new Data();
        new Thread(new Runnable() {
            @Override
            public void run() {
                data.decrease(10);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                data.increase(30);
            }
        }).start();

    }

}

class Data {
    private int money = 100;

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public synchronized void increase(int i) {
        try {
            Thread.sleep(200);// 為了更容易看到線程執行現象
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.money = this.money + i;
        System.out.println(Thread.currentThread().getName() + "賬戶存入" + i + "元,目前賬戶余額為:" + this.money);
    }

    public synchronized void decrease(int i) {
        this.money = this.money - i;
        System.out.println(Thread.currentThread().getName() + "賬戶取出" + i + "元,目前賬戶余額為:" + this.money);
    }

}

 

4.將數據聲明為static的方式

public class MuiltThreadDataShare4 {
    private static int num = 100;

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                increase(100);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                decrease(30);
            }
        }).start();
    }

    public static synchronized void increase(int i) {
        try {
            Thread.sleep(200);// 為了更容易看到線程執行現象
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        num = num + i;
        System.out.println(Thread.currentThread().getName() + "賬戶存入" + i + "元,目前賬戶余額為:" + num);
    }

    public static synchronized void decrease(int i) {
        num = num - i;
        System.out.println(Thread.currentThread().getName() + "賬戶取出" + i + "元,目前賬戶余額為:" + num);
    }

}

 


免責聲明!

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



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