只对写方法加锁而不对读方法加锁则会导致脏读。
1.模拟脏读
public class Account {
String name;
double balance;
/**
* 写方法加锁
* @param name
* @param balance
*/
public synchronized void set(String name, double balance) {
this.name = name;
this.balance = 28.0;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.balance = balance;
}
/**
* 读方法不加锁
* @param name
* @return
*/
public /*synchronized*/ double getBalance(String name) {
return this.balance;
}
public static void main(String[] args) {
Account a = new Account();
// 线程t1写入内容
new Thread(()->a.set("zhangsan", 100.0)).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// t1还没提交
System.out.println(a.getBalance("zhangsan"));
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
// t1已提交
System.out.println(a.getBalance("zhangsan"));
}
}
输出结果:
28.0
100.0
2.解决脏读
public class Account {
String name;
double balance;
/**
* 写方法加锁
* @param name
* @param balance
*/
public synchronized void set(String name, double balance) {
this.name = name;
this.balance = 28.0;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.balance = balance;
}
/**
* 读方法加锁
* @param name
* @return
*/
public synchronized double getBalance(String name) {
return this.balance;
}
public static void main(String[] args) {
Account a = new Account();
// 线程t1写入内容
new Thread(()->a.set("zhangsan", 100.0)).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// t1还没提交
System.out.println(a.getBalance("zhangsan"));// t1没提交 则阻塞
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
// t1已提交
System.out.println(a.getBalance("zhangsan"));
}
}