Java多线程简单案例,单例模式+多线程模拟账户存取款

角色介绍:

1)夫妻账户 (Account)

2)夫 - 存款人 (Husband)

3)妻 - 取款人(Wife)

思路:由于账户的操作必须是原子性的,所以一定是同一时刻同一账户只能被一个人操纵(即使是两个人同时操作手机,对于账户来说,也是有顺序的)因此把账户写成了一个唯一的单例模式。而对该账户的所有操作,都必须是上了锁的。因此账户是重点

以下是代码部分:

一、账户

package com.cloud.test;

import lombok.Data;

import java.math.BigDecimal;

/**
 * 账户
 * @author 
 * @date 2022/1/25 14:59
 */
@Data
public class Account {

    /**
     * 账户操作人
     */
    private String name;

    /**
     * 账户余额
     * 初始化一个0
     */
    private BigDecimal money = new BigDecimal("0");

    private static Account account = null;

    private Account() { }

    /**
     * 单例 - 懒汉
     * @return
     */
    public static Account getInstance(){
        if(null == account){
            synchronized (Account.class){
                if(null == account){
                    account = new Account();
                }
            }
        }
        return account;
    }

    /**
     * 存款
     * @param name 存款人
     * @param money 存款金额
     */
    public synchronized void saveMoney(String name,BigDecimal money){
        this.name = name;
        this.setMoney(this.money.add(money));
        System.out.println(name+"来存钱,存入金额:"+money+",剩余金额:"+this.money);
    }

    /**
     * 取款
     * @param name 取款人
     * @param money 取款金额
     */
    public synchronized void drawMoney(String name,BigDecimal money){
        if(this.money.subtract(money).compareTo(BigDecimal.ZERO) >= 0){
            this.name = name;
            this.setMoney(this.money.subtract(money));
            System.out.println(name+"来取钱,取走金额:"+money+",剩余金额:"+this.money);    
        }else{
            System.out.println(name+"来取钱,账户余额不足!");
        }
    }

    public static void main(String[] args) {
        //初始化一个男人存款
        Husband man = new Husband("N",new BigDecimal("100"));
        //初始化一个女人取款
        Wife women = new Wife("S",new BigDecimal("100"));
        Thread t1 = new Thread(women);
        //Thread t2 = new Thread(women);
        Thread t3 = new Thread(man);
        //Thread t4 = new Thread(man);
        t1.start();
        //t2.start();
        t3.start();
        //t4.start();
    }
}

二、初始化存款对象

package com.cloud.test;

import lombok.Data;

import java.math.BigDecimal;

/**
 * 丈夫 - 负责存款
 * @author 
 * @date 2022/1/25 14:22
 */
@Data
public class Husband implements Runnable{

    private String name;
    
    private BigDecimal money;

    public Husband(String name, BigDecimal money) {
        this.name = name;
        this.money = money;
    }

    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see Thread#run()
     */
    @Override
    public void run() {
        Account account = Account.getInstance();
        int i = 0;
        while (i<15){
            i++;
            account.saveMoney(name,money);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

三、初始化取款对象

package com.cloud.test;

import lombok.Data;

import java.math.BigDecimal;

/**
 * 妻子 - 负责取款
 * @author 
 * @date 2022/1/25 14:29
 */
@Data
public class Wife implements Runnable{
    
    private String name;

    /**
     * 取款金额
     */
    private BigDecimal drawMoney;

    public Wife(String name, BigDecimal drawMoney) {
        this.name = name;
        this.drawMoney = drawMoney;
    }

    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see Thread#run()
     */
    @Override
    public void run() {
        Account account = Account.getInstance();
        int i = 0;
        while(i < 15){
            account.drawMoney(name,drawMoney);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i++;
        }
    }
}

执行结果如下图:

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值