java多線程之髒讀代碼示例及處理

一、髒讀

概念:對於對象的同步和異步的方法,我們在設計自己的程序時,一定要考慮問題的整體性,不然就會出現數據不一致的錯誤,很經典的就是髒讀問題

二、示例

package day005;

/**
*
* 項目名稱:JavaThread
* 類名稱:DirtyRead
* 類描述:業務數據的髒讀問題(對象鎖的同步與異步知識延伸) 
*          要求取出的數據要有一致性,即讀前和讀後 
*         避免髒讀,要保證加鎖的一致性,或加讀寫分離鎖 
* 創建人:liuc
* 創建時間:2018年3月28日 上午10:25:31
* 修改人:liuc
* 修改時間:2018年3月28日 上午10:25:31
* 修改備註:
* @version
*
*/
public class DirtyRead {
    private String username = "aaaa";
    private String password = "123";

    public synchronized void setValue(String username, String password) {
        this.username = username;
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.password = password;
        System.out.println("setValue 最終結果:username=" + username 
            + ",password=" + password);
    };

    //初始時皆有synchronized,爲了反映髒讀問題,去掉該方法的synchronized 
    public synchronized void getValue() {
        System.out.println("getValue 最終結果:username="
         + this.username + ",password=" + this.password);
    }

    public static void main(String[] args) throws InterruptedException {
        final DirtyRead dr = new DirtyRead();
        Thread t1 = new Thread(new Runnable() {

            public void run() {
                dr.setValue("dfa", "456");
            }
        });
        t1.start();
        Thread.sleep(1000);
        dr.getValue();
    }
}

三、代碼分析:

在我們對一個對象的方法加鎖的時候,需要考慮業務的整體性,即爲setValue/getValue方法同時加鎖synchronized同步關鍵字,保證業務(service)的原子性,不然會出現業務錯誤(也從側面保證業務的一致性)

四、執行結果

4.1 setValue/getValue方法同時加鎖synchronized同步關鍵字
這裏寫圖片描述
4.2 getValue方法去掉加鎖synchronized同步關鍵字,就會出現數據髒讀
這裏寫圖片描述

五、總結

在我們對一個對象的方法加鎖的時候,需要考慮業務的整體性,即爲setValue/getValue方法同時加鎖synchronized同步關鍵字,保持業務(service)的原子性,不然會出現業務錯誤(也從側面保證業務的一致性)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章