java多线程实现取款小程序

yizhihongxing

下面是针对Java多线程实现取款小程序的完整攻略。

准备工作

在开始之前,我们需要先了解一些Java多线程方面的基础知识,如线程创建与启动、线程同步、线程通信等。这些知识我们可以通过阅读相关的书籍或者在线教程来学习掌握。

实现步骤

  1. 创建一个银行账户类,包括账户余额、账户号码等属性,以及存、取款等方法。
public class Account {
    private String accountNo;//账户号码
    private double balance;//账户余额
    //省略构造方法、setter和getter方法
    //存款操作
    public synchronized void deposit(double money) {
        balance += money;
        System.out.println(Thread.currentThread().getName() + " 存款 " + money + " 成功,账户余额为:" + balance);
    }
    //取款操作
    public synchronized void withdraw(double money) {
        if (balance >= money) {
            balance -= money;
            System.out.println(Thread.currentThread().getName() + " 取款 " + money + " 成功,账户余额为:" + balance);
        } else {
            System.out.println(Thread.currentThread().getName() + " 取款 " + money + " 失败,余额不足!");
        }
    }
}

在存款和取款操作中,我们使用了synchronized关键字来实现同步,在执行存款或取款操作时,需要对当前的账户对象进行加锁,保证同一时间只有一个线程能够对该账户进行操作。

  1. 创建多个线程进行取款和存款操作。为了更好地展现账户余额的变化,我们可以设置取款和存款线程具有不同的优先级。
public static void main(String[] args){
    Account account = new Account("001", 1000);
    Thread depositThread1 = new Thread(new DepositThread(account), "存款线程1");
    Thread depositThread2 = new Thread(new DepositThread(account), "存款线程2");
    Thread withdrawThread1 = new Thread(new WithdrawThread(account), "取款线程1");
    Thread withdrawThread2 = new Thread(new WithdrawThread(account), "取款线程2");
    depositThread1.setPriority(Thread.MAX_PRIORITY);
    depositThread2.setPriority(Thread.MAX_PRIORITY);
    withdrawThread1.setPriority(Thread.MIN_PRIORITY);
    withdrawThread2.setPriority(Thread.MIN_PRIORITY);
    depositThread1.start();
    depositThread2.start();
    withdrawThread1.start();
    withdrawThread2.start();
}

//存款线程
class DepositThread implements Runnable{
    private Account account;

    public DepositThread(Account account) {
        this.account = account;
    }

    @Override
    public void run() {
        for(int i=0;i<100;i++){
            account.deposit(10);
        }
    }
}

//取款线程
class WithdrawThread implements Runnable{
    private Account account;

    public WithdrawThread(Account account) {
        this.account = account;
    }

    @Override
    public void run() {
        for(int i=0;i<100;i++){
            account.withdraw(10);
        }
    }
}

运行程序后,我们可以看到如下结果:

存款线程1 存款 10.0 成功,账户余额为:1010.0
取款线程1 取款 10.0 成功,账户余额为:1000.0
存款线程1 存款 10.0 成功,账户余额为:1010.0
取款线程2 取款 10.0 成功,账户余额为:1000.0
存款线程1 存款 10.0 成功,账户余额为:1010.0
...

我们可以看到,存款和取款操作依次进行,余额也在正常变化。

  1. 添加取款上限,避免账户余额小于0的情况发生。如果账户余额小于0,则将当前线程阻塞,直到其他线程存款为止。
public synchronized void withdraw(double money) {
    if (balance >= money) {
        balance -= money;
        System.out.println(Thread.currentThread().getName() + " 取款 " + money + " 成功,账户余额为:" + balance);
    } else {
        System.out.println(Thread.currentThread().getName() + " 取款 " + money + " 失败,余额不足!");
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public synchronized void deposit(double money) {
    balance += money;
    System.out.println(Thread.currentThread().getName() + " 存款 " + money + " 成功,账户余额为:" + balance);
    notifyAll();
}

在取款操作中,如果发现账户余额不足,则使用wait()将当前线程阻塞,等待其他线程进行存款操作。在存款操作中,我们使用notifyAll()方法来唤醒之前被阻塞的线程,让它们继续执行。这种方式可以避免账户余额小于0的情况发生。

  1. 实现一个定时器,每隔一段时间自动进行存款操作。例如,我们可以设置每隔10秒钟,自动向账户存入100元。
class AutoDepositTask extends TimerTask {
    private Account account;

    public AutoDepositTask(Account account) {
        this.account = account;
    }

    @Override
    public void run() {
        account.deposit(100);
    }
}

public static void main(String[] args){
    Account account = new Account("001", 1000);
    Timer timer = new Timer();
    timer.schedule(new AutoDepositTask(account), 0, 10000);
    ...
}

我们创建了一个AutoDepositTask类,继承了TimerTask类,并重写了其中的run()方法,用于执行自动存款的操作。在main()方法中,创建了一个Timer对象,并使用schedule()方法设置了定时任务的执行方式。

示例说明

  1. 多个线程同时对同一个账户进行存款和取款操作。由于在存款和取款操作中实现了同步,各线程对账户进行的操作互不干扰,保证了线程安全。
  2. 当余额不足时,取款线程被阻塞。在使用wait()方法将当前线程阻塞时,我们还需要进行异常处理,以保证程序的健壮性。同时,在存款线程中使用notifyAll()唤醒线程时,需要使用同步方法或同步代码块来保证线程安全。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程实现取款小程序 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • JSP使用Common FileUpload组件实现文件上传及限制上传类型实例代码

    下面我将详细讲解”JSP使用Common FileUpload组件实现文件上传及限制上传类型实例代码”的完整攻略。 一、介绍 Common FileUpload 是Apache组织开发的一组基于HTTP的文件上传工具,可以方便地实现文件上传功能。在JSP编程中,常常需要使用到该组件。本文将详细介绍JSP如何使用Common FileUpload组件实现文件上…

    Java 2023年6月15日
    00
  • 深入了解JAVA泛型

    深入了解JAVA泛型 什么是Java泛型? Java泛型是JDK1.5中引入的一个强大的编程概念,它使得我们可以在编译期间有类型安全的访问集合等数据结构,避免了在编译期之后产生的类型转换异常等问题。 泛型的用法 Java泛型主要分为以下几个部分: 1.泛型类 我们可以使用泛型类来创建一个支持泛型的类,泛型类的形式如下: class MyGeneric<…

    Java 2023年5月26日
    00
  • JDBC程序更新数据库中记录的方法

    下面是JDBC程序更新数据库中记录的方法的完整攻略。 更新数据 在JDBC程序中,更新数据使用UPDATE语句,具体步骤如下: 加载JDBC驱动程序 建立数据库连接 创建Statement对象或PreparedStatement对象 准备SQL语句 执行SQL语句 关闭数据库连接 下面是代码示例: // 加载JDBC驱动程序 Class.forName(&q…

    Java 2023年5月19日
    00
  • 解决Maven中关于依赖导入不进的问题

    让我来详细讲解一下“解决Maven中关于依赖导入不进的问题”的完整攻略。 检查maven仓库中是否存在依赖库 首先,我们需要检查maven的本地仓库中是否已经存在了需要导入的依赖库。可以通过在命令行中输入以下命令来查看: mvn dependency:resolve 如果发现有依赖库缺失的情况,那么我们需要手动安装相应的依赖库到本地仓库中。可以通过在命令行中…

    Java 2023年5月20日
    00
  • springboot注解Aspect实现方案

    Spring Boot注解Aspect实现方案 Spring Boot中的注解Aspect是一种AOP编程技术,它可以在不修改原有代码的情况下,对方法进行增强。本文将详细介绍Spring Boot注解Aspect的实现方案,并提供两个示例。 实现方案 Spring Boot中的注解Aspect是通过使用@Aspect注解来实现的。@Aspect注解用于标记一…

    Java 2023年5月15日
    00
  • 详解Java去除json数据中的null空值问题

    详解Java去除json数据中的null空值问题的完整攻略如下: 1.背景和问题描述 在Java开发中,我们处理JSON数据时经常会遇到空值(null)的情况,这些空值会影响JSON数据的可读性、可维护性和可用性。例如,当我们使用的JSON库转换null值时,有些库会将其转换成”null”字符串而有些会将其忽略掉。这种差异会导致一些问题。为了解决这个问题,我…

    Java 2023年5月26日
    00
  • SpringSecurity自定义AuthenticationProvider无法@Autowire的解决

    如果在使用Spring Security时,遇到需要自定义 AuthenticationProvider 的情况,同时自定义的 AuthenticationProvider 中需要使用 @Autowired注入其他的bean,却发现无法注入的情况,此时可以按照以下步骤进行解决。 问题背景 在使用Spring Security时,如果需要自定义 Authent…

    Java 2023年5月20日
    00
  • 命令行编译和执行java代码

    虽然现在IDE很强大又很智能,但是平常随意写点练手的代码的时候,直接在命令行中使用vim和java命令更为方便快捷,可以做到无鼠标纯键盘的操作。 首先保证将java相关指令添加到了环境变量中; 1.编译class文件: javac -d ./ Test.java 编译好的class文件会放置到环境当前目录 (./)中。-d命令的作用是:如果在java文件中定…

    Java 2023年5月4日
    00
合作推广
合作推广
分享本页
返回顶部