许多在单线程情况下的代码放到多线程环境下容易出现线程安全问题
通过模拟取钱过程演示线程安全问题。 一般取钱过程:
1. 用户输入账户、密码,系统判断用户的账户、密码是否匹配。
2. 用户输入取款金额。
3. 系统判断账户余额是否大于取款金额。
4. 如果余额大于取款金额,则取款成功;如果余额小于取款金额,则取款失败。
在模拟过程中就模拟后面三步,没有模拟账户密码验证过程。
代码:public class TakeMoney1Demo {
publicstatic void main(String[] args) {
Accountaccount=new Account("张三", 5000);
TakeMoney1takeMoney1=new TakeMoney1("A",account,900);
TakeMoney1takeMoney2=new TakeMoney1("B",account,4500);
//通过随机数,随机先启动某个线程
Randomrandom=new Random();
intrandomInt=random.nextInt(100);
if(randomInt% 2 ==0) {
takeMoney1.start();
takeMoney2.start();
}else{
takeMoney2.start();
takeMoney1.start();
}
//等待子线程结束
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(account.getNumber()+ "账户最终余额: " + account.getMoney());
}
}
class TakeMoney1 extends Thread{
//谁取钱
privateString name;
//账户
privateAccount account;
//取多少钱
privatedouble takeMoney;
/**
* 构造器
* @param name取钱人
* @param account账户
* @param takeMoney取多少钱
*/
publicTakeMoney1(String name, Account account, double takeMoney) {
super();
this.name= name;
this.account= account;
this.takeMoney= takeMoney;
}
@Override
publicvoid run() {
if(takeMoney<=account.getMoney()){
//模拟取钱成功
System.out.println(this.name+ "取钱成功,取出 " + takeMoney + "元");
//线程暂停 10ms 模拟网络传输
try{
sleep(10);
}catch(InterruptedException e) {
e.printStackTrace();
}
//修改余额
doublemoney=account.getMoney()-takeMoney;
System.out.println(this.name+ "取钱后,计算余额= " + money);
account.setMoney(money);
System.out.println(this.name+ "取钱后,账户: " + account.getNumber()
+"金额为:"+account.getMoney());
}else{
System.out.println(this.name+ "取钱失败,原因: " + account.getNumber() + "账户余额不足");
}
}
}
通过模拟取钱过程演示线程安全问题。 一般取钱过程:
1. 用户输入账户、密码,系统判断用户的账户、密码是否匹配。
2. 用户输入取款金额。
3. 系统判断账户余额是否大于取款金额。
4. 如果余额大于取款金额,则取款成功;如果余额小于取款金额,则取款失败。
在模拟过程中就模拟后面三步,没有模拟账户密码验证过程。
代码:public class TakeMoney1Demo {
publicstatic void main(String[] args) {
Accountaccount=new Account("张三", 5000);
TakeMoney1takeMoney1=new TakeMoney1("A",account,900);
TakeMoney1takeMoney2=new TakeMoney1("B",account,4500);
//通过随机数,随机先启动某个线程
Randomrandom=new Random();
intrandomInt=random.nextInt(100);
if(randomInt% 2 ==0) {
takeMoney1.start();
takeMoney2.start();
}else{
takeMoney2.start();
takeMoney1.start();
}
//等待子线程结束
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(account.getNumber()+ "账户最终余额: " + account.getMoney());
}
}
class TakeMoney1 extends Thread{
//谁取钱
privateString name;
//账户
privateAccount account;
//取多少钱
privatedouble takeMoney;
/**
* 构造器
* @param name取钱人
* @param account账户
* @param takeMoney取多少钱
*/
publicTakeMoney1(String name, Account account, double takeMoney) {
super();
this.name= name;
this.account= account;
this.takeMoney= takeMoney;
}
@Override
publicvoid run() {
if(takeMoney<=account.getMoney()){
//模拟取钱成功
System.out.println(this.name+ "取钱成功,取出 " + takeMoney + "元");
//线程暂停 10ms 模拟网络传输
try{
sleep(10);
}catch(InterruptedException e) {
e.printStackTrace();
}
//修改余额
doublemoney=account.getMoney()-takeMoney;
System.out.println(this.name+ "取钱后,计算余额= " + money);
account.setMoney(money);
System.out.println(this.name+ "取钱后,账户: " + account.getNumber()
+"金额为:"+account.getMoney());
}else{
System.out.println(this.name+ "取钱失败,原因: " + account.getNumber() + "账户余额不足");
}
}
}