diff --git a/src/edu/temple/cis/c3238/banksim/Account.java b/src/edu/temple/cis/c3238/banksim/Account.java index b24877c..adc37ec 100644 --- a/src/edu/temple/cis/c3238/banksim/Account.java +++ b/src/edu/temple/cis/c3238/banksim/Account.java @@ -9,7 +9,7 @@ public class Account { private volatile int balance; private final int id; - private final Bank myBank; + private Bank myBank; public Account(Bank myBank, int id, int initialBalance) { this.myBank = myBank; @@ -38,10 +38,21 @@ public synchronized void deposit(int amount) { // Thread.yield(); // Try to force collision int newBalance = currentBalance + amount; balance = newBalance; + //notifyAll(); } - + @Override public synchronized String toString() { return String.format("Account[%d] balance %d", id, balance); } + + public synchronized void waitForSufficientFunds(int amount) { + while (myBank.isOpen() && amount >= balance) { + try { + wait(); + } catch (InterruptedException ex) { + /*ignore*/ } + } + } + } diff --git a/src/edu/temple/cis/c3238/banksim/Bank.java b/src/edu/temple/cis/c3238/banksim/Bank.java index 5aa1299..e9d06db 100644 --- a/src/edu/temple/cis/c3238/banksim/Bank.java +++ b/src/edu/temple/cis/c3238/banksim/Bank.java @@ -9,15 +9,14 @@ public class Bank { public static final int NTEST = 10; private final Account[] accounts; - private long ntransacts = 0; + private long ntransacts; private final int initialBalance; private final int numAccounts; private boolean waitForTest = false; - //private int threadsPutToSleep = 0; private int threadsSleeping = 0; private int threadsAwake = 10; - + private boolean open = true; public Bank(int numAccounts, int initialBalance) { this.initialBalance = initialBalance; @@ -29,15 +28,31 @@ public Bank(int numAccounts, int initialBalance) { ntransacts = 0; } + synchronized boolean isOpen() { + return open; + } + + void closeBank() { + synchronized (this) { + open = false; + } + for (Account account : accounts) { + synchronized (account) { + account.notifyAll(); + } + } + } + public void transfer(int from, int to, int amount) { -// accounts[from].waitForAvailableFunds(amount); + //accounts[from].waitForSufficientFunds(amount); if (accounts[from].withdraw(amount)) { accounts[to].deposit(amount); - System.out.println("trasnfer has occured"); } + //System.out.println("transfer has occured"); if (shouldTest()) { waitForTest = true; + System.out.println("ntransacts " + ntransacts); } if (waitForTest) { @@ -45,12 +60,10 @@ public void transfer(int from, int to, int amount) { // put each thread to sleep and track threadsPutToSleep/Awake sleepTransferThread(); } - } - public synchronized void test() { + public void test() { int sum = 0; - System.out.println("Test Start"); for (Account account : accounts) { System.out.printf("%s %s%n", Thread.currentThread().toString(), account.toString()); @@ -66,69 +79,70 @@ public synchronized void test() { System.out.println(Thread.currentThread().toString() + " The bank is in balance"); } - - //Reset the signal for threads to sleep back to false - waitForTest = false; - this.setThreadsSleeping(0); - //Test is complete, wake up all threads - notifyAll(); - } - - public int size() { - return accounts.length; - } - - public boolean shouldTest() { - return ++ntransacts % NTEST == 0; } public synchronized void sleepTransferThread() { - //Threads are put to sleep upon completion of last transfer - this.incrThreadsSleeping(); - - //long threadId = Thread.currentThread().getId(); - //System.out.println("thread " + threadId/*this.getThreadsSleeping()*/ + " put to sleep"); - System.out.println("thread " + this.getThreadsSleeping() + " put to sleep"); - System.out.println("thread " + this.getThreadsAwake() + " still awake"); - System.out.println("ntransactions = " + this.ntransacts); - - //Last thread to sleep creates new thread to run test - if (this.getThreadsAwake() == 1 /* this.threadsSleeping == NTEST*/) { - System.out.println("Inside Test Condition"); - Thread t = new Thread(new Sum(this)); - t.start(); + //System.out.println("threads awake " + this.getThreadsAwake()); + //Last thread to wait creates new thread to run test + if (this.getThreadsAwake() == 1) { + Sum sum = new Sum(this); + sum.start(); } + //Thread is about to wait, adjust count + this.incrThreadsSleeping(); + while (waitForTest) { try { - wait(); + this.wait(); } catch (InterruptedException ex) { } } + //Thread has resumed running, adjust count + this.decrThreadsSleeping(); } - - public synchronized int getThreadsSleeping() { + + //Pretty sure I didn't need any of these but to afraid to take them out + public int getThreadsSleeping() { return threadsSleeping; } - public synchronized int getThreadsAwake() { + public int getThreadsAwake() { return threadsAwake; } - public synchronized void setThreadsSleeping(int i) { + public void setThreadsSleeping(int i) { this.threadsSleeping = i; this.threadsAwake = NTEST - 0; } - public synchronized void incrThreadsSleeping() { + public void incrThreadsSleeping() { this.threadsSleeping++; this.threadsAwake--; } - public synchronized void decrThreadsSleeping() { + public void decrThreadsSleeping() { this.threadsSleeping--; this.threadsAwake++; } + + public long incrNtransacts() { + this.ntransacts++; + return ntransacts; + } + + public int size() { + return accounts.length; + } + + public void setFlagFalse() { + this.waitForTest = false; + } + + public boolean shouldTest() { + return incrNtransacts() % NTEST == 0; + } + } diff --git a/src/edu/temple/cis/c3238/banksim/Sum.java b/src/edu/temple/cis/c3238/banksim/Sum.java index 17b59eb..f53ee8f 100644 --- a/src/edu/temple/cis/c3238/banksim/Sum.java +++ b/src/edu/temple/cis/c3238/banksim/Sum.java @@ -18,8 +18,12 @@ public Sum(Bank b) { } @Override - public synchronized void run() { + public void run() { + synchronized(bank){ bank.test(); + bank.setFlagFalse(); + bank.notifyAll(); + } } } diff --git a/src/edu/temple/cis/c3238/banksim/TransferThread.java b/src/edu/temple/cis/c3238/banksim/TransferThread.java index 9190d04..b86b873 100644 --- a/src/edu/temple/cis/c3238/banksim/TransferThread.java +++ b/src/edu/temple/cis/c3238/banksim/TransferThread.java @@ -18,12 +18,15 @@ public TransferThread(Bank b, int from, int max) { @Override public void run() { - for (int i = 0; i < 1000; i++) {///////////////////////////////change 1000 back to 10000 + 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); - //System.out.println(i); + //System.out.println(Thread.currentThread().toString() + " i = " + i); + if(i == 9999) + System.out.println("For loop complete!"); } + //bank.closeBank(); } }