Head First Java中多个线程同时取款,为什么会出现余额不足的问题?

ID:17056 / 打印

head first java中多个线程同时取款,为什么会出现余额不足的问题?

head first java中的线程问题

问题:

在以下这段代码中,我们创建了两个线程来分别执行ryanandmonicajob类的run方法。每个线程对bankaccount对象进行取款操作,并在取款前检查账户余额是否大于等于取款金额。然而,输出结果却令人惊讶。

代码:

立即学习“Java免费学习笔记(深入)”;

class bankaccount {      private int balance = 100;      public int getbalance() {         return balance;     }      public void withdraw(int amount) {         balance = balance - amount;     } }  public class ryanandmonicajob implements runnable {      private bankaccount account = new bankaccount();      public static void main(string[] args) {         ryanandmonicajob thejob = new ryanandmonicajob();         thread one = new thread(thejob);         thread two = new thread(thejob);         one.setname("ryan");         two.setname("monica");         one.start();         two.start();     }      public void run() {         for (int x = 0; x < 10; x++) {             makewithdrawal(10);             if (account.getbalance() < 0) {                 system.out.println("overdrawn!");             }         }     }      private void makewithdrawal(int amount) {         string currentthread = thread.currentthread().getname();         if (account.getbalance() >= amount) {             system.out.println(currentthread + " is about to withdraw");             try {                 system.out.println(currentthread + " is going to sleep");                 thread.sleep(500);             } catch (interruptedexception ex) {                 ex.printstacktrace();             }             system.out.println(currentthread + " woke up.");             account.withdraw(amount);             system.out.println(currentthread + " completes the withdrawal");         } else {             system.out.println("sorry, not enough for " + currentthread);         }     } }

输出:

ryan is about to withdraw ryan: sorry, not enough for ryan monica: is about to withdraw ...

问题原因:

当ryan线程执行makewithdrawal方法时,它先输出"ryan is about to withdraw",然后进入sleep状态。然而,这并不是像你想象的那样交出控制权给另一个线程。相反,在这个sleep时间内,monica线程仍然继续执行,并且已经检测到账户余额不足,所以输出"ryan: sorry, not enough for ryan"。

一旦ryan线程从sleep状态中苏醒,它继续执行makewithdrawal方法。此时,账户余额已经发生了变化,并且不再足以支持取款操作。因此,它输出"monica is about to withdraw"。

解决方法:

为了避免这种不同步,我们可以在makewithdrawal方法中使用synchronized块来确保账户对象的访问是同步的。

private void makeWithdrawal(int amount) {     synchronized (account) {         String currentThread = Thread.currentThread().getName();         if (account.getBalance() >= amount) {             System.out.println(currentThread + " is about to withdraw");             try {                 System.out.println(currentThread + " is going to sleep");                 Thread.sleep(500);             } catch (InterruptedException ex) {                 ex.printStackTrace();             }             System.out.println(currentThread + " woke up.");             account.withdraw(amount);             System.out.println(currentThread + " completes the withdrawal");         } else {             System.out.println("Sorry, not enough for " + currentThread);         }     } }
上一篇: 如何解决 FastJson 解析 2M 大字符串报错?
下一篇: Post请求发送数据时遇到空指针异常,如何排查原因?

作者:admin @ 24资源网   2024-11-27

本站所有软件、源码、文章均有网友提供,如有侵权联系308410122@qq.com

与本文相关文章

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。