一、模拟场景
1、提供一个账户类Account.java作为创建共享资源账户对象的类。
2、定义一个线程类,创建两个线程小红和小明,同时在一个账户上取钱。
3、会出现从账户中多取钱的现象。
二、代码
1、账户类
package com.zjl.study.多线程.线程安全问题模拟;
/**
* Created by zjl 2022/5/28
**/
public class Account {
private String cardId;
private double money;
public void drawMoney(double money) {
// 1、获取是哪个线程来取钱
String name = Thread.currentThread().getName();
// 2、判断余额是否足够
if (this.money >= money) {
System.out.println(name + "来取钱,余额足够,吐出" + money + "元");
// 3、更新余额
this.money -= money;
System.out.println(name + "来取钱后,余额剩余:" + this.money);
} else {
System.out.println(name + "来取钱,余额不足!");
}
}
public Account() {
}
public Account(String cardId, double money) {
this.cardId = cardId;
this.money = money;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
2、线程类
package com.zjl.study.多线程.线程安全问题模拟;
/**
* Created by zjl 2022/5/28
* <p>
* 线程类:用来创建取钱线程对象
**/
public class DrawThread extends Thread {
// 定义一个成员变量来接收账户对象
private Account account;
public DrawThread(Account account, String name) {
// 调用父类的构造方法给线程起名字
super(name);
this.account = account;
}
@Override
public void run() {
// 调用取钱方法,取钱10000,小明线程和小红线程取钱时都调用此方法
account.drawMoney(10000);
}
}
3、创建小明、小红两个线程,同时在一个账户里面取钱。
package com.zjl.study.多线程.线程安全问题模拟;
/**
* Created by zjl 2022/5/28
**/
public class ThreadSafe {
public static void main(String[] args) {
// 1、创建一个共享资源:账户对象
Account account = new Account("123", 10000);
// 2、创建小明、小红两个线程对象去账户对象中取钱
DrawThread xiaoMing = new DrawThread(account,"小明线程");
xiaoMing.start();
DrawThread xiaoHong = new DrawThread(account,"小红线程");
xiaoHong.start();
}
}