(尽信书则不如无书,实践是检验真理的唯一标准。)
Java线程安全
存取款,同一个账户存取款活动只能同时进行一个,且必须是在存款后取款,取款后存款。
关于账户的代码,线程同步和通讯都在里面,剩下的需要两个线程,一个是存钱一个是取钱。即生产者消费者的例子。
public class Account {
private long accountNumber;
private int balance;
private boolean flag = false;//
public Account(long accountNumber, int balance) {
super();
this.accountNumber = accountNumber;
this.balance = balance;
}
public int getBalance() {
return balance;
}
public synchronized void draw(int amount) {
try {
if (!flag) {
wait();
System.out.println("no money");
} else {
if (amount <= balance) {
balance -= amount;
System.out.println("取钱成功:" + amount);
} else {
System.out.println("取钱失败 剩余余额: " + balance);
}
flag = false;
System.out.println(flag);
notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("yichang quqian");
}
System.out.println("draw end");
}
public synchronized void deposite(int amount) {
try {
if (flag) {
wait();
System.out.println("no poc");
} else {
balance += amount;
System.out.println("存款成功,余额:" + balance);
flag = true;
System.out.println(flag);
notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("yichang cunqian");
}
System.out.println("deposite end");
}
}
结果如下
存款成功,余额:100
true
deposite end
no money
draw end
取钱成功:100
false
draw end
no poc
deposite end
存款成功,余额:100
true
deposite end
no money
draw end
取钱成功:100
false
draw end
no poc
deposite end
存款成功,余额:100
true
deposite end
no money
draw end
取钱成功:100
false
draw end
no poc
deposite end
结果分析不太对,原因在于wait之后使用notify唤起的是从wait之后的代码开始执行,也就是说else里的代码在从新执行期间不会再次执行。(上述代码参考与疯狂JAVA讲义第三版,可能作者没插入代码的时候没太注意也可能jdk版本不同造成)。
修正后代码
package cn.ruiz.stu.synchornized1;
public class Account {
private long accountNumber;
private int balance;
private boolean flag = false;//
public Account(long accountNumber, int balance) {
super();
this.accountNumber = accountNumber;
this.balance = balance;
}
public int getBalance() {
return balance;
}
public synchronized void draw(int amount) {
try {
if (!flag) {
wait();
System.out.println("no money");
}
// else {
if (amount <= balance) {
balance -= amount;
System.out.println("取钱成功:" + amount);
} else {
System.out.println("取钱失败 剩余余额: " + balance);
}
flag = false;
System.out.println(flag);
notifyAll();
// }
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("yichang quqian");
}
System.out.println("draw end");
}
public synchronized void deposite(int amount) {
try {
if (flag) {
wait();
System.out.println("no poc");
}
// else {
balance += amount;
System.out.println("存款成功,余额:" + balance);
flag = true;
System.out.println(flag);
notifyAll();
// }
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("yichang cunqian");
}
System.out.println("deposite end");
}
}
存款成功,余额:100
true
deposite end
no money
取钱成功:100
false
draw end
no poc
存款成功,余额:100
true
deposite end
no money
取钱成功:100
false
draw end
no poc
存款成功,余额:100
true
deposite end
no money
取钱成功:100
false
draw end
no poc
存款成功,余额:100
true
deposite end
no money
取钱成功:100
false
draw end
no poc
存款成功,余额:100
true
deposite end
no money
取钱成功:100
false
draw end
no poc
存款成功,余额:100
true
deposite end
no money
取钱成功:100
false
draw end