目的:
1、学会分析“银行存款程序”的实现思路。
2、根据思路独立完成“银行存款程序”的源代码编写、编译及运行。
3、通过存款程序理解多线程安全问题的发生原因,并掌握如何解决多线程安全问题。
要求:
编写一个模拟银行存款的程序。假设有两个储户都去银行往同一个账户存款,一次存100,每人存3次。要求储户每存一次钱,账·户余额增加100元,并在控制台输出当前账户的余额。
二、实验原理(图):
1、通过任务描述可以看出,该任务需要使用多线程相关知识来实现。由于两个储户同时操作一个账户,因此需要创建两个线程来完成存款操作。由于此处账户为共享数据,所以需要使用实现Runnable接口的方式来创建线程,而不是继承Thread类。
2、既然是储户去银行存款,那么可以得出该任务会涉及到3个类,分别是银行类、储户类和测试类。
3、在银行类中需要定义一个账户余额的变量和一个存款的方法,储户类是任务类,需要实现Runnable接口,并在类中覆写run()方法,通过循环3次调用银行类中的存款方法,来实现往同一个账户存款3次的操作。
4、为了避免每一次存款过程中账户的余额增加时可能出现的不正常情况,也就是避免多线程并发问题,需要在特定的位置上使用同步代码块并指定一个锁,该锁可以是任意的对象,此处使用this关键字,即可解决多线程安全问题。
public class Bank {
static String bankname;// 定义静态变量存储银行名称
private String name;// 账户姓名
private String password;// 密码
private double balance;// 账户余额
private double turnover;// 交易额
// 静态方法,打印出银行欢迎语句
static void welcome() {
System.out.println("欢迎来到" + bankname + "---------"); }
// 构造方法,开户
public Bank(String name, String password, double turnover) {
// 将变量赋值给成员变量
super();
this.name = name;
this.password = password;
this.turnover = turnover;
this.balance = turnover - 10; }
// 存款
public synchronized void deposit(double turnover) {
balance = balance + turnover;
System.out.println(name + "您好,您的账户 已存入" + turnover + "元," + "当前余额" + balance + "元");}
// 取款
public synchronized void withdrawal(String password, double turnover) {
// 根据传入的变量与成员变量进行比较,判断密码是否正确
if (this.password != password) {
System.out.println("您输入的密码错误!");
return;}
// 判断余额是否充足
if (balance - turnover > 0) {
balance = balance - turnover;
System.out.println(name + "您好,您的账户 已取出" + turnover + "元," + "当前余额" + balance + "元");
} else {
System.out.println("对不起,账户余额不足!");}}
// 静态方法,打印出银行欢迎下次光临的语句
static void welcomeNext() {
System.out.println("请携带好随身物品,欢迎下次光临" + bankname + "---------");}}
//创建一个存钱类SaveMoney去实现接口Runnable:
class SaveMoney implements Runnable{
private Bank bank;
public SaveMoney(Bank bank) {
super();
this.bank = bank; }
public void run() {
bank.deposit(500);//每次存入500元}}
//创建一个取钱类FetMoney去实现接口Runnable:
class GetMoney implements Runnable{
private Bank bank;
public GetMoney(Bank bank) {
super();
this.bank = bank; }
public void run() {
bank.withdrawal("654321",200);//每次取200元 }}
//创建一个测试类去输入数据测试程序:
package 第八次聊天程序设计;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 开卡的时候默认存入100元,卡费10元
Bank bank = new Bank("王光辉先生", "654321", 100);
bank.bankname = "招商银行";
bank.welcome();
// 模拟5次客户的存取款过程,线程调度是随机的,也就是不确定下一次客户是存款还是取款
Thread t1, t2;
for (int i = 1; i <= 5; i++) {
SaveMoney s1 = new SaveMoney(bank);
t1 = new Thread(s1);
t1.start(); // 启动存钱线程
GetMoney s2 = new GetMoney(bank);
t2 = new Thread(s2);
t2.start();// 启动取钱线程} }}
版权声明:本文为F__lower原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。