模拟場景:
寫一段小程式,一個方法給某人賬戶充值,另一個方法查詢某人的賬戶,如果兩個方法都不加鎖,并發情況下肯定會問題,現在隻給充值方法加鎖,查詢方法不加,由于synchronized與非synchronized方法可以同時運作,是以查詢方法可能産生髒讀問題。
public class Account {
String name;
double balance;
public synchronized void setBalance(String name, double balance) {
this.name = name;
try {
Thread.sleep(2000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
this.balance = balance;
}
public double getBalance(String name) {
if (name.equals(this.name)) {
return this.balance;
}
return 0.0;
}
public static void main(String[] args) throws InterruptedException {
Account acc = new Account();
new Thread(() -> acc.setBalance("張三", 100)).start();
TimeUnit.SECONDS.sleep(1);//暫停1秒
/**
* setBalance還未執行完成,讀到的還是balance的預設值,即0.0,也就是髒讀
*/
System.out.println(acc.getBalance("張三"));
TimeUnit.SECONDS.sleep(2);//再暫停3秒
/**
* setBalance已執行完成,讀到的是balance的最新值,即100.0
*/
System.out.println(acc.getBalance("張三"));
}
}
結果
0.0
100.0
是否需要給讀方法同時加上synchronized?看需求,如果需求場景允許出現髒讀(僅僅是讀,不進行任何寫操作),可以不用加,加上synchronized性能将急劇下降,如果場景不允許髒讀,該加還是要加。
另
public synchronized double getBalance(String name) {
if (name.equals(this.name)) {
return this.balance;
}
return 0.0;
}
public double getBalance(String name) {
synchronized (this) {
if (name.equals(this.name)) {
return this.balance;
}
return 0.0;
}
}
public static synchronized void fun(){
// to do something
}
//等價于
public static void fun(){
synchronized(Account.class){
// to do something
}
}