Банковский симулятор с синхронизацией на JavaJAVA

Программисты JAVA общаются здесь
Anonymous
Банковский симулятор с синхронизацией на Java

Сообщение Anonymous »

У меня есть метод Transfer(), который снимает деньги с одного счета и перекладывает их на другой. Есть 10 учетных записей, каждая из которых работает со своим потоком. У меня есть еще один метод test(), который суммирует сумму на каждом счете, чтобы убедиться, что банк не потерял и не получил деньги. Чтобы получить точную сумму, я создал логический флаг, указывающий, выполняется ли тестирование. Если да, то мне нужно как-то приостановить передачи до завершения теста. Я попытался реализовать это с помощью синхронизированного блока, чтобы сообщить потокам дождаться выполнения условия и освободиться, как только условие перестанет быть истинным. По какой-то причине у меня возникают трудности. Мой метод передачи выглядит следующим образом:

public class Bank {

public static final int NTEST = 10;
private Account[] accounts;
private long ntransacts = 0;
private int initialBalance;
private int numAccounts;
private boolean open;
private int transactsInProgress;
private boolean testing=false;

public Bank(int numAccounts, int initialBalance) {
open = true;
this.initialBalance = initialBalance;
this.numAccounts = numAccounts;
accounts = new Account[numAccounts];
for (int i = 0; i < accounts.length; i++) {
accounts = new Account(this, i, initialBalance);
}
ntransacts = 0;
transactsInProgress = 0;
}
public synchronized void incrementTransacts(){
transactsInProgress++;
}
public synchronized void decrementTransacts(){
transactsInProgress--;
}

public void transfer(int from, int to, int amount) throws InterruptedException {

accounts[from].waitForAvailableFunds(amount);
synchronized(this){
while(testing){
System.out.println("Cannot transfer while testing...");
this.wait();
}
}
if (!open) return;
if (accounts[from].withdraw(amount)) {
incrementTransacts(); //synchronzied method increments transactsInProgress
accounts[to].deposit(amount);
decrementTransacts(); //synchronized method
}
if (shouldTest()) test();

synchronized(this){
this.notifyAll();
}
}

public synchronized void test() throws InterruptedException {
int sum = 0;

testing=true;
while(transactsInProgress!=0){
System.out.println("Cannot test while transactions are in progres... \nWaiting...");
wait();
}

for (int i = 0; i < accounts.length; i++) {
System.out.printf("%s %s%n",
Thread.currentThread().toString(),accounts.toString());
sum += accounts.getBalance();
}
System.out.println(Thread.currentThread().toString() +
" Sum: " + sum);
if (sum != numAccounts * initialBalance) {
System.out.println(Thread.currentThread().toString() +
" Money was gained or lost");
System.exit(1);
} else {
System.out.println(Thread.currentThread().toString() +
" The bank is in balance");
}
testing=false;
notifyAll();
}
public int size() {
return accounts.length;
}

public synchronized boolean isOpen() {return open;}

public void closeBank() {
synchronized (this) {
open = false;
}
for (Account account : accounts) {
synchronized(account) {
account.notifyAll();
}
}
}

public synchronized boolean shouldTest() {
return ++ntransacts % NTEST == 0;
}
}


Прошло много времени с тех пор, как я программировал на Java, и я новичок в потоках и параллелизме, поэтому я не уверен, в чем именно я ошибаюсь. Когда я запускаю программу, сумма банка неверна. На каждом счете по 10 000, поэтому сумма каждый раз должна составлять 100 000. Есть идеи?

EDIT: класс потока и Main:

class TransferThread extends Thread {

public TransferThread(Bank b, int from, int max) {
bank = b;
fromAccount = from;
maxAmount = max;
}

@Override
public void run() {
for (int i = 0; i < 10000; i++) {
int toAccount = (int) (bank.size() * Math.random());
int amount = (int) (maxAmount * Math.random());
bank.transfer(fromAccount, toAccount, amount);
}
bank.closeBank();
}
private Bank bank;
private int fromAccount;
private int maxAmount;
}


Основное:

public static void main(String[] args) throws InterruptedException {
Bank b = new Bank(NACCOUNTS, INITIAL_BALANCE);
Thread[] threads = new Thread[NACCOUNTS];
// Start a thread for each account
for (int i = 0; i < NACCOUNTS; i++) {
threads = new TransferThread(b, i, INITIAL_BALANCE);
threads.start();
}
// Wait for all threads to finish
for (int i = 0; i < NACCOUNTS; i++) {
try {
threads.join();
} catch (InterruptedException ex) {
// Ignore this
}
}
b.test();
}


Подробнее здесь: https://stackoverflow.com/questions/325 ... on-in-java

Вернуться в «JAVA»