模拟银行开户
/**
* 面试题:模拟银行账户
* 对业务写方法加锁
* 对业务读方法不加锁
* 这样行不行?
*
* 容易产生脏读问题(dirtyRead)
*/
package com.mashibing.juc.c_008;
import java.util.concurrent.TimeUnit;
public class Account {
String name;
double balance;
public synchronized void set(String name, double balance) {
this.name = name;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.balance = balance;
}
public /*synchronized*/ double getBalance(String name) {
return this.balance;
}
public static void main(String[] args) {
Account a = new Account();
new Thread(()->a.set("zhangsan", 100.0)).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(a.getBalance("zhangsan"));
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(a.getBalance("zhangsan"));
}
}
|
出现0这个脏读数据。
原因:加锁方法和不加锁方法是可以同步进行的,因为加了锁set方法尚未把balance赋值成功就进入睡眠,然后就会启动未加锁的getBalance方法,因为balance此时为赋制成功,故获得的值为0.当set方法睡眠时间过去,进入running状态,此时balance赋值为100