当前位置: 首页 > 知识库问答 >
问题:

帐户余额未更新-线程同步Java

周良弼
2023-03-14

所以我有一个任务来创建一个程序,它有一个起始余额为1的银行账户。然后,我创建了一组卡,可以访问该帐户、存款或取款,但不能同时进行。我创建了许多线程,然后使用这些线程访问银行帐户,提取或存入随机金额,然后退出。

我的卡片类别:

public class card implements Runnable {
private int id;
private account account;
private int count = 1;


card(int id, account acc1){
    this.id = id;
    this.account = acc1;

}

public int getid(){
    return this.id;
}

public int localBalance(){
    return account.getBalance();
}


public void run() {
    for(count = 0; count <= 5; count++) { //withdraw and deposit random amounts
        int transactionamount = (int)(Math.random()*10);
        if (Math.random() > 0.5) {
        System.out.printf("%-12s%-12s%-12s%-12s\n","card id:(" + getid() + ")"," ",transactionamount, account.getBalance());
        account.deposit(transactionamount);
        } else {
        System.out.printf("%-12s%-12s%-12s%-12s\n","card id:(" + getid() + ")",transactionamount," ",account.getBalance());
        account.withdraw(transactionamount);

        }
        }
        }
}

我的帐户类别:

public class account {

private int balance = 5000;


public account(int balance){
    this.balance = balance;
}

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

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

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


public synchronized void setNewBalance(int localBalance) { //no longer in use
    balance = localBalance;
}

}

我的课程

public class Program {

public static void main(String[] args ) throws InterruptedException {
    // TODO Auto-generated method stub

    int numberofcards = 5;
    int accountbalance = 5000;


    card cardArray[] = new card[numberofcards];

    account acc1 = new account(accountbalance); //pass into account the starting balance.

    System.out.printf("\n%-12s%-12s%-12s%-12s\n","Transaction","Withdrawal","Deposit","Balance");
    System.out.printf("%-12s%-12s%-12s%-12s\n"," "," "," ",accountbalance + "\n");

    Thread[] threads = new Thread[numberofcards];

    for(int i = 1; i < numberofcards; i++ ){ 
       cardArray[i] = new card(i, acc1);
       threads[i] = new Thread(cardArray[i]);
       threads[i].start();
    }
    for(int i = 1; i < threads.length; i++ ){
       threads[i].join();
    }
    System.out.printf("\n%-12s%-12s%-12s%-12s\n","finished"," "," ","Final Balance: " + acc1.getBalance()); 


}

}

输出示例:

http://puu.sh/lvoE5/05ebcd4c74.png

正如你所看到的,它对每一张不同的卡都有效,它回到5000,然后随机存取一笔钱。我似乎不明白为什么我的代码不经常更新金额。任何帮助都将是惊人的,我很惊讶我自己已经走到了这一步。

编辑:删除了不需要的新线程。连接代码

编辑2:仍然不工作,直接使用“立即支取和存款”。链接中附加的输出

共有2个答案

公西国发
2023-03-14

这应该可以工作,请注意帐户类中的正确同步

账户:

public class Account {
    private int bankBalance;

    public Account(int initialBankBalance) {
        this.bankBalance = initialBankBalance;
    }

    public synchronized int withdraw(int cardId, int amount) {
        bankBalance = bankBalance - amount;
        System.out.println("Card: " + cardId + "; withdraw: " + amount + "; after withdrawal: " + bankBalance);
        return bankBalance;
    }

    public synchronized int deposit(int cardId, int amount) {
        bankBalance = bankBalance + amount;
        System.out.println("Card: " + cardId + "; deposit: " + amount + "; after deposit: " + bankBalance);
        return bankBalance;
    }

    public synchronized int getBankBalance() {
        return bankBalance;
    }
}

卡片:

public class Card implements Runnable {
    private int id;
    private Account account;

    public Card(int id, Account account) {
        this.account = account;
        this.id = id;
    }

    @Override
    public void run() {
        double depositTotal = 0;
        double withdrawTotal = 0;
        for (int i = 0; i < 5; i++) {
            if (Math.random() > 0.5) {
                int deposit = (int) (Math.random() * 10);
                depositTotal = depositTotal + deposit;
                account.deposit(id, deposit);
            } else {
                int withdraw = (int) (Math.random() * 10);
                withdrawTotal = withdrawTotal + withdraw;
                account.withdraw(id, withdraw);
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("Card: " + id + "; withdrawal total: " + withdrawTotal);
        System.out.println("Card: " + id + "; deposit total: " + depositTotal);
    }
}

节目:

    public class Program {

    public static void main(String[] args) throws InterruptedException {
        int numCards = 2;
        int initialBankBalance = 1000;

        Account account = new Account(initialBankBalance);
        System.out.println("Starting balance: " + initialBankBalance);

        Thread[] threads = new Thread[numCards];

        for (int i = 0; i < numCards; i++) {
            Thread thread = new Thread(new Card(i+1, account));
            thread.start();
            threads[i] = thread;
        }

        for (int i = 0; i < threads.length; i++) {
            threads[i].join();
        }

        System.out.println("End balance is : " + account.getBankBalance());

    }
}

示例运行的输出:

Starting balance: 1000
Card: 1; deposit: 3; after deposit: 1003
Card: 2; withdraw: 1; after withdrawal: 1002
Card: 2; deposit: 6; after deposit: 1008
Card: 1; deposit: 3; after deposit: 1011
Card: 1; withdraw: 7; after withdrawal: 1004
Card: 2; deposit: 1; after deposit: 1005
Card: 1; deposit: 0; after deposit: 1005
Card: 2; withdraw: 7; after withdrawal: 998
Card: 1; withdraw: 2; after withdrawal: 996
Card: 2; withdraw: 7; after withdrawal: 989
Card: 2; withdrawal total: 15.0
Card: 1; withdrawal total: 9.0
Card: 2; deposit total: 7.0
Card: 1; deposit total: 6.0
End balance is : 989
冯宏恺
2023-03-14

您的代码存在多个问题,首先是您的测试代码永远不会像我猜想的那样交织在一起。

考虑以下代码:

  for(int i = 1; i < numberofcards; i++ ){ //create amount of cards in array of cards
      cardArray[i] = new card(i, acc1);
      new Thread(cardArray[i]).start();
      new Thread(cardArray[i]).join();
  }

对于每个循环,您创建两个线程对象(请参阅new关键字),其中一个启动线程,另一个调用加入。由于第二个线程没有运行,所以它只是返回,什么也不做。

此外,由于您的run方法是同步的,所以该类中的任何新的同步的方法都不会同时运行,这毫无意义。请参见:您应该同步run方法吗?为什么还是为什么不?

这大概就是你想要的:

Thread threads = new Threads[numberofcards];
for(int i = 1; i < numberofcards; i++ ){ 
   cardArray[i] = new card(i, acc1);
   threads[i] = new Thread(cardArray[i]);
   threads[i].start();
}
for(int i = 1; i < threads.length; i++ ){
   threads[i].join();
}

你用$5000初始化每张卡。信用卡余额=账户。getBalance()并更新此。信用卡余额。然后在帐户中更新帐户。setNewBalance(cardBalance)但是,在设置局部变量和写入帐户期间,其他线程也获取并更新了帐户的卡余额。您对帐户的修改不是原子性的。

您不应该使用局部变量来表示卡中帐户的余额。这违反了独立实体规则,没有合法目的。

 类似资料:
  • 我想在取款后把账户上的余额换一下,但它只是停留在10点。我不知道如何在SavingsAccount中正确应用一个会改变它的方法。我试了但没有成功。

  • 问题内容: 我有以下表格,分别是BankDetails和Transactiondetails。使用这两个表,我想获得帐户名称的当前余额。 表格: 插入两个表的脚本: 输出将是这样的: 我需要使用以上两个表格输入帐户持有人姓名,帐户编号和当前余额。 下面是我的查询,我想获得优化的查询,即如果可能的话不使用子查询。 注意: 在我的情况下,贷方=添加到帐户中的金额,借方=从帐户中扣除的金额。 对于未遵循

  • 问题内容: 我想使用原始sql来计算帐户余额,而无需额外的应用程序逻辑。交易模式包括金额,from_account_id和to_account_id 我的查询是 而且它没有按我预期的那样工作-结果是错误的,但是如果我仅在事务正常运行后才加入交易,例如只需借记金额就可以 我在余额查询中错过了什么? http://sqlfiddle.com/#!15/b5565/1 问题答案: 基本上,您正在计算a和

  • 这是代码参考的参数。创建AccountSavings类。该类有两个实例变量:一个用于保持年利率的双变量和一个用于保持储蓄平衡的双变量。年利率为5.3,储蓄余额为100美元 •创建计算月利息的方法。•创建一个方法来运行两个线程。使用匿名类创建这些线程。第一个线程调用每月利息计算方法12次,然后显示储蓄余额(第12个月的余额)。之后,该线程Hibernate5秒。第二个线程调用每月利息计算方法12次,

  • 我正在编程一个GUI(银行账户)。一切正常;但面对在JPanel中显示当前余额的问题,它应该在我点击提交按钮时显示余额。我尝试过许多不同的方法,但仍然不成功。 我的信息在JTextArea中正确显示。 但是我不能让它在第三个JGroup(“当前金额”)中显示金额。我在JTextField中输入的金额并单击提交,它应该显示在JGroup(“当前金额”)中。 每当我输入一个人的相同id并单击提交按钮时

  • 下面的代码创建了一个新的custom um < code > Thread ,并等待线程结束,直到主线程再次激活。 > < li >我不太明白它是如何工作的。为什么< code > myth read . wait();立即接到电话? < li> 为什么不改用< code>Thread.join()? 公共静态void main(String[] args) {