• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于java:存款取款数据一致性小案例

java 搞代码 4年前 (2022-01-27) 37次浏览 已收录 0个评论

问题:开户为10000,其中张三隔一段时间会存入100,李四会隔一段时间进行取款100,王五会过一段时间取款200,存入金额不能超过20000,当取款为0时,进行,如何保障该阶段的数据一致性问题
解决方案:将开户金额设置为atomic原子类,同时取款贷款设置为synchronized即可解决该问题

开户类Account

<code class="java">package com.currency.currency05;

import lombok.Data;

import java.util.concurrent.atomic.AtomicInteger;

@Data
public class Account {
    private String name;
    private AtomicInteger amount;

    public void name() {
        System.out.println("账户为:" + name + "!");
    }

    public synchronized boolean deposit(String threadName, Integer change) {
        amount.addAndGet(change);
        if(amount.get() > 20000) {
            System.out.print("贷款金额曾经达到下限,贷款失败");
            return false;
        }
        System.out.println("01:" + threadName+",贷款金额为"+change + ",开始贷款,贷款后余额为" + amount);
        return true;
    }

    public synchronized  boolean withdraw(String threadName, Integer money) {
        if (amount.get() <= 0 || amount.get() < money) {
            System.out.println(threadName+",账户金额为"+amount.get()+",你的取款金额为"+money+",取款失败");
            return false;
        } else {
            amount.addAndGet(-money);
            System.out.println("02:" + threadName+",取款金额为"+money + ",开始取款,取款后余额为" + amount);
            return true;
        }
    }

    public synchronized void openAccount(String name, Integer money) {
        this.name = name;
        this.amount = new AtomicInteger(money);
        System.out.println("00:" + name + "开户胜利,开户金额为"+money);
    }
}

取款类Deposit

<code class="java">package com.currency.currency05;

import lombok.Data;

import java.util.Random;

@Data
public class Deposit implements Runnable{
    private Account account;

    private int deposit;

    public void deposit(Account account, int deposit) {
        this.account = account;
        this.deposit = deposit;
    }


    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        while (true) {
            if (account.getAmount().get() < 20000) {
                boolean isFlag = account.deposit(threadName, deposit);
                if (!isFlag) {
                    break;
                }
                try {
                    Thread.sleep(new Random().nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (account.getAmount().get() >= 20000) {
                break;
            }
            if (account.getAmount().get() == 0) {
                System.out.println("余额为零,贷款完结");
                break;
            }
        }
    }
}

贷款类Withdraw

<code class="java">package com.currency.currency05;

import java.util.Random;

/**
 * @author huanglaoxie(微信:yfct-8888)
 * @className Withdraw
 * @description:
 * @date 2017/12/20 10:16
 */
public class Withdraw implements Runnable{

    private Account account;

    private int withdraw;

    public void withdraw(Account account, int withdraw) {
        this.account = account;
        this.withdraw = withdraw;
    }

    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        while (true) {
            if (account.getAmount().get() > 0) {
                boolean isFlag = account.withdraw(threadName, withdraw);
                if (!isFlag) {
                    break;
                }

                try {
                    Thread.sleep(new Random().nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            } else {

                break;
            }
        }
    }
}

线程执行

<code class="java">package com.currency.currency05;


public class Test {

    public static void main(String[] args) {
        Account account = new Account();
        account.openAccount("zhouzhou", 10000);

        Deposit p1 = new Deposit();
        p1.deposit(account, 100);
        Thread depositThread = new Thread(p1, "张三");

        Withdraw p2 = new Withdraw();
        p2.withdraw(account, 100);
        Thread withdrawThread1 = new Thread(p2, "李四");

        Withdraw p3 = new Withdraw();
        p3.withdraw(account, 200);
        Thread withdrawThread2 = new Thread(p3, "王五");
        withdrawThread1.start();
        withdrawThread2.start();
        depositThread.start();


    }

}

测试后果

<code class="java">/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/bin/java -Dvisualvm.id=220271645666 -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=49342:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/legacy8ujsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/openjsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/lib/tools.jar:/Users/suyuzhou/Downloads/currency05/target/classes:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/boot/spring-boot-starter/2.5.5/spring-boot-starter-2.5.5.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/boot/spring-boot/2.5.5/spring-boot-2.5.5.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/spring-context/5.3.10/spring-context-5.3.10.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/spring-aop/5.3.10/spring-aop-5.3.10.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/spring-beans/5.3.10/spring-beans-5.3.10.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/spring-expression/5.3.10/spring-expression-5.3.10.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/boot/spring-boot-autoconfigure/2.5.5/spring-boot-autoconfigure-2.5.5.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/boot/spring-boot-starter-logging/2.5.5/spring-boot-starter-logging-2.5.5.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/ch/qos/logback/logback-classic/1.2.6/logback-classic-1.2.6.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/ch/qos/logback/logback-core/1.2.6/logback-core-1.2.6.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/apache/logging/log4j/log4j-to-slf4j/2.14.1/log4j-to-slf4j-2.14.1.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/apache/logging/log4j/log4j-api/2.14.1/log4j-api-2.14.1.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/slf4j/jul-to-slf4j/1.7.32/jul-to-slf4j-1.7.32.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/jakarta/annotation/jakarta.annotation-api/1.3.5/jakarta.annotation-api-1.3.5.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/spring-core/5.3.10/spring-core-5.3.10.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/springframework/spring-jcl/5.3.10/spring-jcl-5.3.10.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/yaml/snakeyaml/1.28/snakeyaml-1.28.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/projectlombok/lombok/1.18.20/lombok-1.18.20.jar:/Users/suyuzhou/coding/maven/apache-maven-3.8.1/localRepository/org/slf4j/slf4j-api/1.7.32/slf4j-api-1.7.32.jar com.currency.currency05.Test
00:zhouzhou开户胜利,开户金额为10000
02:李四,取款金额为100,开始取款,取款后余额为9900
01:张三,贷款金额为100,开始贷款,贷款后余额为10000
02:王五,取款金额为200,开始取款,取款后余额为9800
02:王五,取款金额为200,开始取款,取款后余额为9600
01:张三,贷款金额为100,开始贷款,贷款后余额为9700
02:李四,取款金额为100,开始取款,取款后余额为9600
02:王五,取款金额为200,开始取款,取款后余额为9400
01:张三,贷款金额为100,开始贷款,贷款后余额为9500
01:张三,贷款金额为100,开始贷款,贷款后余额为9600
02:王五,取款金额为200,开始取款,取款后余额为9400
02:王五,取款金额为200,开始取款,取款后余额为9200
02:李四,取款金额为100,开始取款,取款后余额为9100
02:王五,取款金额为200,开始取款,取款后余额为8900
01:张三,贷款金额为100,开始贷款,贷款后余额为9000
02:李四,取款金额为100,开始取款,取款后余额为8900
02:王五,取款金额为200,开始取款,取款后余额为8700
02:李四,取款金额为100,开始取款,取款后余额为8600
02:李四,取款金额为100,开始取款,取款后余额为8500
02:王五,取款金额为200,开始取款,取款后余额为8300
01:张三,贷款金额为100,开始贷款,贷款后余额为8400
02:李四,取款金额为100,开始取款,取款后余额为8300
02:李四,取款金额为100,开始取款,取款后余额为8200
02:王五,取款金额为200,开始取款,取款后余额为8000
01:张三,贷款金额为100,开始贷款,贷款后余额为8100
02:李四,取款金额为100,开始取款,取款后余额为8000
01:张三,贷款金额为100,开始贷款,贷款后余额为8100
02:王五,取款金额为200,开始取款,取款后余额为7900
02:李四,取款金额为100,开始取款,取款后余额为7800
01:张三,贷款金额为100,开始贷款,贷款后余额为7900
02:王五,取款金额为200,开始取款,取款后余额为7700
01:张三,贷款金额为100,开始贷款,贷款后余额为7800
02:李四,取款金额为100,开始取款,取款后余额为7700
01:张三,贷款金额为100,开始贷款,贷款后余额为7800
02:李四,取款金额为100,开始取款,取款后余额为7700
02:李四,取款金额为100,开始取款,取款后余额为7600
01:张三,贷款金额为100,开始贷款,贷款后余额为7700
02:王五,取款金额为200,开始取款,取款后余额为7500
02:李四,取款金额为100,开始取款,取款后余额为7400
02:李四,取款金额为100,开始取款,取款后余额为7300
01:张三,贷款金额为100,开始贷款,贷款后余额为7400
01:张三,贷款金额为100,开始贷款,贷款后余额为7500
02:李四,取款金额为100,开始取款,取款后余额为7400
02:王五,取款金额为200,开始取款,取款后余额为7200
02:王五,取款金额为200,开始取款,取款后余额为7000
02:王五,取款金额为200,开始取款,取款后余额为6800
01:张三,贷款金额为100,开始贷款,贷款后余额为6900
02:李四,取款金额为100,开始取款,取款后余额为6800
02:王五,取款金额为200,开始取款,取款后余额为6600
01:张三,贷款金额为100,开始贷款,贷款后余额为6700
02:王五,取款金额为200,开始取款,取款后余额为6500
02:李四,取款金额为100,开始取款,取款后余额为6400
01:张三,贷款金额为100,开始贷款,贷款后余额为6500
01:张三,贷款金额为100,开始贷款,贷款后余额为6600
02:李四,取款金额为100,开始取款,取款后余额为6500
01:张三,贷款金额为100,开始贷款,贷款后余额为6600
02:王五,取款金额为200,开始取款,取款后余额为6400
02:李四,取款金额为100,开始取款,取款后余额为6300
01:张三,贷款金额为100,开始贷款,贷款后余额为6400
01:张三,贷款金额为100,开始贷款,贷款后余额为6500
02:李四,取款金额为100,开始取款,取款后余额为6400
02:王五,取款金额为200,开始取款,取款后余额为6200
02:李四,取款金额为100,开始取款,取款后余额为6100
02:李四,取款金额为100,开始取款,取款后余额为6000
01:张三,贷款金额为100,开始贷款,贷款后余额为6100
02:王五,取款金额为200,开始取款,取款后余额为5900
02:王五,取款金额为200,开始取款,取款后余额为5700
02:李四,取款金额为100,开始取款,取款后余额为5600
01:张三,贷款金额为100,开始贷款,贷款后余额为5700
02:李四,取款金额为100,开始取款,取款后余额为5600
02:王五,取款金额为200,开始取款,取款后余额为5400
01:张三,贷款金额为100,开始贷款,贷款后余额为5500
01:张三,贷款金额为100,开始贷款,贷款后余额为5600
02:王五,取款金额为200,开始取款,取款后余额为5400
02:王五,取款金额为200,开始取款,取款后余额为5200
02:李四,取款金额为100,开始取款,取款后余额为5100
02:李四,取款金额为100,开始取款,取款后余额为5000
01:张三,贷款金额为100,开始贷款,贷款后余额为5100
02:王五,取款金额为200,开始取款,取款后余额为4900
02:李四,取款金额为100,开始取款,取款后余额为4800
02:王五,取款金额为200,开始取款,取款后余额为4600
01:张三,贷款金额为100,开始贷款,贷款后余额为4700
02:李四,取款金额为100,开始取款,取款后余额为4600
02:王五,取款金额为200,开始取款,取款后余额为4400
02:李四,取款金额为100,开始取款,取款后余额为4300
01:张三,贷款金额为100,开始贷款,贷款后余额为4400
01:张三,贷款金额为100,开始贷款,贷款后余额为4500
02:王五,取款金额为200,开始取款,取款后余额为4300
02:李四,取款金额为100,开始取款,取款后余额为4200
02:王五,取款金额为200,开始取款,取款后余额为4000
02:李四,取款金额为100,开始取款,取款后余额为3900
02:李四,取款金额为100,开始取款,取款后余额为3800
01:张三,贷款金额为100,开始贷款,贷款后余额为3900
01:张三,贷款金额为100,开始贷款,贷款后余额为4000
02:王五,取款金额为200,开始取款,取款后余额为3800
01:张三,贷款金额为100,开始贷款,贷款后余额为3900
02:李四,取款金额为100,开始取款,取款后余额为3800
02:王五,取款金额为200,开始取款,取款后余额为3600
02:李四,取款金额为100,开始取款,取款后余额为3500
02:王五,取款金额为200,开始取款,取款后余额为3300
02:王五,取款金额为200,开始取款,取款后余额为3100
02:李四,取款金额为100,开始取款,取款后余额为3000
01:张三,贷款金额为100,开始贷款,贷款后余额为3100
02:李四,取款金额为100,开始取款,取款后余额为3000
02:王五,取款金额为200,开始取款,取款后余额为2800
01:张三,贷款金额为100,开始贷款,贷款后余额为2900
01:张三,贷款金额为100,开始贷款,贷款后余额为3000
01:张三,贷款金额为100,开始贷款,贷款后余额为3100
02:王五,取款金额为200,开始取款,取款后余额为2900
02:李四,取款金额为100,开始取款,取款后余额为2800
02:王五,取款金额为200,开始取款,取款后余额为2600
01:张三,贷款金额为100,开始贷款,贷款后余额为2700
01:张三,贷款金额为100,开始贷款,贷款后余额为2800
01:张三,贷款金额为100,开始贷款,贷款后余额为2900
02:李四,取款金额为100,开始取款,取款后余额为2800
01:张三,贷款金额为100,开始贷款,贷款后余额为2900
02:王五,取款金额为200,开始取款,取款后余额为2700
01:张三,贷款金额为100,开始贷款,贷款后余额为2800
02:李四,取款金额为100,开始取款,取款后余额为2700
02:王五,取款金额为200,开始取款,取款后余额为2500
01:张三,贷款金额为100,开始贷款,贷款后余额为2600
02:王五,取款金额为200,开始取款,取款后余额为2400
02:王五,取款金额为200,开始取款,取款后余额为2200
02:李四,取款金额为100,开始取款,取款后余额为2100
02:李四,取款金额为100,开始取款,取款后余额为2000
02:王五,取款金额为200,开始取款,取款后余额为1800
01:张三,贷款金额为100,开始贷款,贷款后余额为1900
02:李四,取款金额为100,开始取款,取款后余额为1800
02:王五,取款金额为200,开始取款,取款后余额为1600
01:张三,贷款金额为100,开始贷款,贷款后余额为1700
01:张三,贷款金额为100,开始贷款,贷款后余额为1800
02:王五,取款金额为200,开始取款,取款后余额为1600
02:李四,取款金额为100,开始取款,取款后余额为1500
01:张三,贷款金额为100,开始贷款,贷款后余额为1600
02:王五,取款金额为200,开始取款,取款后余额为1400
01:张三,贷款金额为100,开始贷款,贷款后余额为1500
02:王五,取款金额为200,开始取款,取款后余额为1300
02:王五,取款金额为200,开始取款,取款后余额为1100
01:张三,贷款金额为100,开始贷款,贷款后余额为1200
02:李四,取款金额为100,开始取款,取款后余额为1100
02:王五,取款金额为200,开始取款,取款后余额为900
02:王五,取款金额为200,开始取款,取款后余额为700
01:张三,贷款金额为100,开始贷款,贷款后余额为800
02:李四,取款金额为100,开始取款,取款后余额为700
02:王五,取款金额为200,开始取款,取款后余额为500
01:张三,贷款金额为100,开始贷款,贷款后余额为600
02:李四,取款金额为100,开始取款,取款后余额为500
02:王五,取款金额为200,开始取款,取款后余额为300
02:李四,取款金额为100,开始取款,取款后余额为200
01:张三,贷款金额为100,开始贷款,贷款后余额为300
02:李四,取款金额为100,开始取款,取款后余额为200
02:王五,取款金额为200,开始取款,取款后余额为0
余额为零,贷款完结

Process finished with exit code 0

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于java:存款取款数据一致性小案例
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址