一.同步代码块锁
账户类代码
锁在此,this表示该锁对象仅对应当前账户
public class Account {
private String accID;
private double balance;
public Account() {
}
public Account(String accID, double balance) {
this.accID = accID;
this.balance = balance;
}
public String getAccID() {
return accID;
}
public void setAccID(String accID) {
this.accID = accID;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public void withdraw(double money){
String name = Thread.currentThread().getName();
synchronized (this) {
if (this.balance >= money){
System.out.println(name+ " withdraw succeed, amount is:"+money);
this.balance -= money;
System.out.println("After "+name+"'s withdraw, the balance changed to: "+ balance);
}else {
System.out.println(name + "'s withdraw failed'.");
}
}
}
}
取钱线程类
public class withdrawThr extends Thread {
private Account acc;
public withdrawThr(Account acc,String name) {
super(name);
this.acc = acc;
}
@Override
public void run() {
acc.withdraw(100000.0);
}
}
执行体类
public class threadSyncDemo1 {
public static void main(String[] args) {
Account acc = new Account("MTU_010203",100000);
new withdrawThr(acc,"Peter").start();
new withdrawThr(acc,"Diana").start();
}
}
二.取钱方法加synchronized修饰,锁默认会用this作为锁对象
经测试,直接锁方法,会让住线程里代码顺序在上的总是先进入方法
而代码块锁不一定
public synchronized void withdraw(double money){
String name = Thread.currentThread().getName();
if (this.balance >= money){
System.out.println(name+ " withdraw succeed, amount is:"+money);
this.balance -= money;
System.out.println("After "+name+"'s withdraw, the balance changed to: "+ balance);
}else {
System.out.println(name + "'s withdraw failed'.");
}
}
三.在账户类定义一个Lock的成员变量,final修饰
把要锁的代码块,前后用Lock变量的lock和unlock方法包起来
这种方法,主线程中顺序在下的子线程仍有小概率先抢到锁
为了防止程序异常,无法解锁,要把unlock方法放在try_final的final语句里
public class Account {
private String accID;
private double balance;
/**用final修饰,锁对象对同时调用本账户的线程来说,唯一,不可变,体现专业性*/
private final Lock lock = new ReentrantLock();
public Account() {
}
public Account(String accID, double balance) {
this.accID = accID;
this.balance = balance;
}
public String getAccID() {
return accID;
}
public void setAccID(String accID) {
this.accID = accID;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public void withdraw(double money){
public void withdraw(double money){
try {
String name = Thread.currentThread().getName();
lock.lock();
if (this.balance >= money){
System.out.println(name+ " withdraw succeed, amount is:"+money);
this.balance -= money;
System.out.println("After "+name+"'s withdraw, the balance changed to: "+ balance);
}else {
System.out.println(name + "'s withdraw failed'.");
}
} finally {
lock.unlock();
}
}
}