Ich lese gerade das Buch "Parallele und Verteilte Anwendung in Java" von Hanser. Damit man die Probleme beim Zugriff auf gemeinsam genutzte Objekt erkennen kann, gibt es im Buch ein Beispiel mit stark vereinfachter Form einer Bank. Eine Bank verwaltet mehrere Konten (Account). Für jede Angestellte der Bank (Clerk) wird ein Thread realisiert. Diese Threads führen Buchungen auf den Konten durch. Dabei soll von jedem Thread aus der Zugriff auf jedes Konto möglich sein.
Class Account:
Class Bank:
Class Clerk:
Class Banking enthält die Main Methode:
Die Methode getBanlanceByAccountNumber() hab ich dazu geschrieben, um den Kontostand eines Accounts bei einer Bank zu kriegen. Wenn es richtig funktioniert mit synchronized, dann bei der esten Ausgabe muss der aktuelle Kontostand des Accounts 47 500 und bei der zweiten 800 sein. Ich bekomme aber manchmal 500 und 200 (d.h Petra Schmitt führt keine Buchung auf Konto 47 aus???), manchmal 500 und 500 (keine Buchung wird ausgeführt???). Ich kann wirklich nicht verstehen warum. Kann jemand es mir bitte erklären?
Class Account:
Code:
public class Account {
private float balance; // Kontostand
public float getBalance() {
return balance;
}
public void setBalance(float balance) {
this.balance = balance;
}
}
Class Bank:
Code:
public class Bank {
private Account[] accounts;
public Bank() {
accounts = new Account[100];
for (int i = 0; i < accounts.length; i++) {
accounts[i] = new Account();
}
}
public void transferMoney(int accountNumber, float amount) {
synchronized (accounts[accountNumber]) {
float oldBalance = accounts[accountNumber].getBalance();
float newBalance = oldBalance + amount;
accounts[accountNumber].setBalance(newBalance);
}
}
public void getBalanceByAccountNumber(int accountNumber) {
System.out.println("Der aktuelle Kontostand des Accounts " + accountNumber + " ist: " + accounts[accountNumber].getBalance());
}
}
Class Clerk:
Code:
public class Clerk extends Thread {
private Bank bank;
private int accountNumber;
private float amount;
public Clerk(String name, Bank bank, int accountNumber, float amount) {
super(name);
this.bank = bank;
this.accountNumber = accountNumber;
this.amount = amount;
start();
}
@Override
public void run() {
bank.transferMoney(accountNumber, amount);
}
}
Class Banking enthält die Main Methode:
Code:
public class Banking {
public static void main(String[] args) {
Bank myBank = new Bank();
// Geld auf Kontonr 47 einzahlen
myBank.transferMoney(47, 500);
myBank.getBalanceByAccountNumber(47);
// Andrea Müller und Petra Schmitt führen gleichzeitig Buchung auf Konto 47 aus
new Clerk("Andrea Müller", myBank, 47, -300);
new Clerk("Petra Schmitt", myBank, 47, 600);
myBank.getBalanceByAccountNumber(47);
}
}
Die Methode getBanlanceByAccountNumber() hab ich dazu geschrieben, um den Kontostand eines Accounts bei einer Bank zu kriegen. Wenn es richtig funktioniert mit synchronized, dann bei der esten Ausgabe muss der aktuelle Kontostand des Accounts 47 500 und bei der zweiten 800 sein. Ich bekomme aber manchmal 500 und 200 (d.h Petra Schmitt führt keine Buchung auf Konto 47 aus???), manchmal 500 und 500 (keine Buchung wird ausgeführt???). Ich kann wirklich nicht verstehen warum. Kann jemand es mir bitte erklären?