[英]Account Balance doesnt update - thread synchronization Java
因此,我有一个任务来创建一个程序,该程序有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,然后随机存入或提取。 我似乎无法弄清楚为什么我的代码没有不断更新金额。 任何帮助都将是惊人的,无论如何我都感到很惊讶。
编辑:摆脱了不需要的新线程.join代码并摆脱了我的run方法中的同步,但是输出仍然相同,但是,请继续指出问题,关于线程的自我教育确实很困难,所以请记住。 先感谢您
编辑2:仍然无法使用,请立即使用提现和存款。 输出附加在链接中
您的代码存在多个问题 ,首先是您的测试代码永远不会交织,就像我怀疑的那样。
考虑以下代码:
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
关键字) ,对于一个循环,您将启动线程,对于另一个循环,您将调用join
。 由于第二个线程未运行, 因此它只是返回而什么也不做 。
此外,由于您的run
方法是同步的,所以该类中任何新的synchronized
方法都不会同时运行,这毫无意义。 请参阅: 您是否应该同步运行方法? 为什么或者为什么不?
这可能是您想要的:
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 this.cardBalance = account.getBalance()
初始化每张卡,然后更新this.cardBalance
。 然后,您在account.setNewBalance(cardBalance)
更新帐户,但是在设置局部变量和写入帐户期间,其他线程也已获取并更新了帐户的卡余额。 您对该帐户的修改不是原子的。
您不应该使用局部变量来表示卡中帐户的余额。 这违反了单独的实体规则,并且没有合法目的。
这应该起作用,注意Account类中的正确同步
帐户:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.