一、髒讀
概念:對於對象的同步和異步的方法,我們在設計自己的程序時,一定要考慮問題的整體性,不然就會出現數據不一致的錯誤,很經典的就是髒讀問題
二、示例
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)的原子性,不然會出現業務錯誤(也從側面保證業務的一致性)。