public class DirtyRead {
private String username = "xxoo";
private String password = "1234";
/**
* 這是一個同步方法
*/
public synchronized void setValue(String username, String password) {
this.username = username;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.password = password;
System.out.println("setValue 最終結果: username = " + username + ", password = " + password);
}
/**
* 這是一個異步方法
*/
public void getValue() {
System.out.println("getValue 最終結果: username = " + username + ", password = " + password);
}
public static void main(String[] args) throws InterruptedException {
final DirtyRead dr = new DirtyRead();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
dr.setValue("王五", "909090");
}
});
t1.start();
Thread.sleep(1000);
dr.getValue();
}}
運行結果:
image.png
上述代碼可以發現t1線程執行setValue 方法時,主線程隨后去調用getValue方法。讀取出來的數據只有username改變了,但是password沒變。獲取了一個意料之外的結果。
這個原因是setValue是個同步方法,getValue是個異步方法。且在兩個線程調用一個對象的兩個方法時,導致了數據不一致,這就是所謂的臟讀。
為了結果一致性,我們需要在getValue方法上也加上synchronized 修飾。保證業務的一致性。