Java设计模式之外观模式示例详解
311
2022-07-29
最近java学到了多线程编程中的线程同步问题,教材中的取款小程序对于理解线程和线程同步很有帮助,在此将其补充完善.
1、建立java类
这里建立了三个java类,第一个Account类,用于封装账户中的各种信息;第三个DrawThread类用于实现线程体;第二个类主要封装了主函数
2、Account类
public class Account {
//封装账户编号,账户余额和两个成员变量
private String accountNo;
private double balance;
public http://Account(){};
public Account(String accountNo,double balance){
this.accountNo=accountNo;
this.balance=balance;
}
public void setAccountNo(String accountNo)
{
this.accountNo=accountNo;
}
public void setBalance(double balance){
this.balance=balance;
}
public String getAccountNo(){
return accountNo;
}
public double getBalance(){
return balance;
}
public int hashCode(){
return accountNo.hashCode();
}
public boolean equals(Object obj){
if(this==obj){
return true;
}
if (obj!=null&&obj.getClass()==Account.class){
Account target=(Account)obj;
return target.getAccountNo().equals(accountNo);
}
return false;
}
}
3、DrawThread类
public class DrawThread extends Thread {
//模拟用户账户
private Account account;
//当前取钱线程所希望的取钱数
private double drawAmount;
public DrawThread(String name, Account account, double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
//当多个线程修改同一个共享数据时,将涉及数据安全问题
public void run() {
//使用account作为同步监视器,任何线程进入下面同步代码块之前
//必须先获得对account账户的锁定——其他线程无法获得锁,也就无法修改它
synchronized (account) {
if (account.getBalance() >= drawAmount) {
//吐出钞票
System.out.println(getName() + "取钱成功!吐出钞票:" + drawAmount);
/*
try {
Thread.sleep(1);
}catch (InterruptedException ex)
{
ex.printStackTrace();
}
*/
//修改余额
account.setBalance(account.getBalance() - drawAmount);
http://System.out.println("\t余额为:"http:// + account.getBalance());
} else {
System.out.println(getName() + "取钱失败!余额不足!");
}
}
}
}
4、DrawTest类
public class DrawTest {
public static void main(String[] args){
//创建一个账户
Account acct=new Account("1234567",1000);
//模拟两个线程对同一个账户取钱
new DrawThread("jack",acct,800).start();
new DrawThread("rose",acct,800).start();
}
}
运行结果:
以上程序有一点需要注意,就是用到了同步代码块。它可以解决run()方法不具备同步安全性(即当两个线程同时发送请求时即会造成异常)
同步代码块:
synchronized (obj){
//需要执行的代码
}
如果我们去掉run()方法中的同步代码块,继续运行
Account acct=new Account("1234567",1000);
new DrawThread("jack",acct,800).start();
new DrawThread("rose",acct,800).start();
(银行账户一共1000元,Jack和rose分别对同一账户取钱)
运行结果:
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~