0
点赞
收藏
分享

微信扫一扫

一把锁引发的问题,synchronized方法与非synchronized方法共存产生数据脏读问题

模拟场景:

写一段小程序,一个方法给某人账户充值,另一个方法查询某人的账户,如果两个方法都不加锁,并发情况下肯定会问题,现在只给充值方法加锁,查询方法不加,由于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
}
}


举报

相关推荐

0 条评论