java多线程实现取款小程序

下面是针对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日

相关文章

  • 详解MyBatis Generator自动创建代码(dao,mapping,poji)

    下面我将详细讲解MyBatis Generator自动创建代码的完整攻略,包括使用步骤和示例说明。 MyBatis Generator是什么 MyBatis Generator是MyBatis框架家族中的一员,是一款自动生成MyBatis持久层代码(Mapper接口和Mapper XML文件)的工具。它是根据数据库表结构自动生成对应的JavaBean、Map…

    Java 2023年6月1日
    00
  • 详解springboot springsecuroty中的注销和权限控制问题

    下面是详解springboot springsecuroty中的注销和权限控制问题的完整攻略。 1. 概述 Spring Security是Spring框架的安全框架,可以实现身份认证、权限控制、防护攻击等功能。在Spring Boot中,可以使用Spring Security来保护web应用程序的安全性。而注销和权限控制是Spring Security中常…

    Java 2023年5月20日
    00
  • java实现上传图片进行切割的方法

    下面我来详细讲解一下Java实现上传图片进行切割的方法。 1. 背景 在Web开发中,上传图片并对其进行切割是非常常见的操作。通常情况下,我们需要将大图片切割成多张小图片,以方便我们的页面显示。那么如何实现这样的功能呢? 2. 技术实现 2.1 文件上传 首先要实现的便是文件上传,可以采用常用的一些Java框架,如SpringMVC或Struts2来实现。 …

    Java 2023年5月20日
    00
  • 手动编译并运行Java项目实现过程解析

    手动编译并运行Java项目的过程可以分为以下步骤: 1. 编写Java代码 首先,我们需要编写Java代码。可以使用任何文本编辑器编写Java代码,只需要将代码保存为.java文件即可。例如,我们可以创建一个名为HelloWorld.java的文件,并将以下代码复制到其中: public class HelloWorld { public static vo…

    Java 2023年5月19日
    00
  • Java动态编译执行代码示例

    我将详细讲解“Java动态编译执行代码示例”的完整攻略,过程中将包含两条示例说明。 什么是Java动态编译执行代码? Java动态编译执行代码是一种在程序运行时动态编译源代码的方式,并将其转换为可以直接执行的代码。这种方式可以帮助开发者实现灵活的功能,使得程序更容易适应不同的运行环境。 实现Java动态编译执行代码的流程 实现Java动态编译执行代码通常分为…

    Java 2023年5月26日
    00
  • Sprint Boot @ConditionalOnProperty使用方法详解

    @ConditionalOnProperty是Spring Boot中的一个注解,它用于根据配置属性的值来决定是否启用或禁用某个组件。在使用Spring Boot开发应用程序时,@ConditionalOnProperty是非常有用的。本文将详细介绍@ConditionalOnProperty的作用和使用方法,并提供两个示例说明。 @ConditionalO…

    Java 2023年5月5日
    00
  • Java实现树形结构的示例代码

    让我来详细讲解如何使用Java实现树形结构的示例代码。 什么是树形结构? 在计算机科学中,树形结构是一种抽象数据类型,它模拟了树的结构,例如一棵家谱树。 Java实现树形结构的示例代码 在Java中,我们可以通过使用类来模拟树形结构。一个基本的树形结构类应该包括以下几个元素: 节点类(Node) 树形结构类(Tree) 以下是一个示例代码: class No…

    Java 2023年5月19日
    00
  • mac系统下载、安装、使用Java8教程

    Mac系统下载、安装、使用Java8教程 下载Java8 在Mac系统上下载Java8有两种方式: 1. Oracle官网下载 访问Oracle官网,找到对应的JDK版本并下载,具体下载步骤如下: 找到“Java SE Development Kit 8 Downloads”,点击“Download”按钮。 接受许可协议,选择对应的操作系统下载JDK安装包。…

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