【任务描述】

编写一个模拟银行存款的程序。假设有两个储户都去银行往同一个帐户存款,一次存 100,每人存 3 次。要求储户每存一次钱,帐户余额增加 100,并在控制条输出当前帐户的余额。

【实现思路】

  1. 通过任务描述,该任务需要使用多线程相关知识来实现。由于两个储户同时操作一个帐户,因此需要创建两个线程来完成存款操作。由于此处帐户为共享数据,所以需要使用 Runnable 接口的方式来创建线程,而不是继承 Thread 类。
  2. 既然是储户去银行存款,那么可以得出该任务会涉及到 3 个类,分别是银行类、储户类和测试类。
  3. 在银行类中需要定义一个帐户余额的变量和一个存款的方法。储户类是任务类,需要实现 Runnable 接口,并在类中重写 run()方法,通过循环 3 次调用银行类中的存款方法,来实现往同一个帐户存款 3 次的操作。
  4. 为了避免每一次存款过程中帐户的余额增加时可能出现的不正常情况,也就是避免多线程并发问题,需要在特定的位置上使用同步代码块并指定一个锁,该锁可以是任意的对象,此处使用 this 关键字,即可解决多线程安全问题。

【代码实现】

1、创建银行类

定义一个银行类,实现账户存款的功能,如下所示:

  1. public class Bank {
  2. private int sum;
  3. static Object a = new Object();
  4. public void add(int num) {
  5. synchronized (a) {
  6. sum = sum + num;
  7. System.out.println(Thread.currentThread().getName() + "往帐户存入 100 元,现帐户余额为:" + sum);
  8. }
  9. }
  10. }

2、创建储户类

定义一个储户类,实现储户去银行存 3 次钱的功能,如下所示:

  1. public class Customer implements Runnable {
  2. private Bank b = new Bank();
  3. @Override
  4. public void run() {
  5. // TODO Auto-generated method stub
  6. for (int i = 0; i < 3; i++) {
  7. b.add(100);
  8. }
  9. }
  10. }

3、创建测试类

定义测试类方法,在类中创建客户对象,并创建和开启两个线程执行存款操作,如下所示:

  1. public class SaveMoneyTest {
  2. public static void main(String[] args) {
  3. Customer c = new Customer();
  4. new Thread(c, "小王").start();
  5. new Thread(c, "小李").start();
  6. // Thread 小王 = new Thread(c);
  7. // Thread 小李 = new Thread(c);
  8. // 小王.start();
  9. // 小李.start();
  10. }
  11. }

4、运行结果

QQ截图20200711140002.png