Java多线程并发问题:模拟银行账户存款取款

以下Java代码模拟了银行账户的存款和取款操作,并演示了多线程环境下可能出现的并发问题:

public class BankAccount {
    private int balance;

    public BankAccount(int initialBalance) {
        balance = initialBalance;
    }

    public synchronized void deposit(int amount) {
        balance += amount;
    }

    public synchronized void withdraw(int amount) {
        balance -= amount;
    }

    public synchronized int getBalance() {
        return balance;
    }
}

public class Accountant implements Runnable {
    private BankAccount account;

    public Accountant(BankAccount account) {
        this.account = account;
    }

    public void run() {
        for (int i = 0; i < 10000; i++) {
            account.deposit(1);
        }
    }
}

public class Cashier implements Runnable {
    private BankAccount account;

    public Cashier(BankAccount account) {
        this.account = account;
    }

    public void run() {
        for (int i = 0; i < 10000; i++) {
            account.withdraw(1);
        }
    }
}

public class Bank {
    public static void main(String[] args) {
        BankAccount account = new BankAccount(10000);

        Thread t1 = new Thread(new Accountant(account));
        Thread t2 = new Thread(new Cashier(account));

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println('Final balance: ' + account.getBalance());
    }
}

问题分析

代码中,Accountant线程模拟存款操作,Cashier线程模拟取款操作。由于两个线程都并发的对同一个BankAccount对象进行操作,而且depositwithdraw方法没有进行同步处理,因此会出现数据不一致的问题。

例如,假设初始余额为10000,Accountant线程执行deposit(1)操作时,首先读取当前余额为10000,然后将其加1得到10001,但在写入新余额之前,Cashier线程也执行了withdraw(1)操作,同样读取到余额为10000,将其减1得到9999,并写入新余额。最终导致Accountant线程的存款操作被覆盖,余额变成9999,而不是预期的10001。

解决方案

为了解决这个问题,我们需要对depositwithdraw方法进行同步控制,确保同一时间只有一个线程可以修改账户余额。在本例中,我们使用synchronized关键字来实现同步控制。

通过将depositwithdraw方法声明为synchronized,我们可以确保在任何时刻只有一个线程可以执行这些方法。当一个线程正在执行depositwithdraw方法时,其他线程将被阻塞,直到该线程完成操作并释放锁。

总结

多线程并发访问共享资源是Java编程中常见的问题,如果不进行同步控制,就会导致数据不一致等问题。synchronized关键字是Java提供的一种简单有效的同步机制,可以帮助我们解决这类问题。

Java多线程并发问题:模拟银行账户存款取款

原文地址: https://www.cveoy.top/t/topic/jmi8 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录