The program will read the file like this,
> java homework6/Bank small.txt 4
acct:0 bal:999 trans:1
acct:1 bal:1001 trans:1
acct:2 bal:999 trans:1
acct:3 bal:1001 trans:1
acct:4 bal:999 trans:1
acct:5 bal:1001 trans:1
acct:6 bal:999 trans:1
acct:7 bal:1001 trans:1
acct:8 bal:999 trans:1
acct:9 bal:1001 trans:1
acct:10 bal:999 trans:1
acct:11 bal:1001 trans:1
acct:12 bal:999 trans:1
acct:13 bal:1001 trans:1
acct:14 bal:999 trans:1
acct:15 bal:1001 trans:1
acct:16 bal:999 trans:1
acct:17 bal:1001 trans:1
acct:18 bal:999 trans:1
acct:19 bal:1001 trans:1
Each text file looks something like:
1 2 1
3 4 1
5 6 1
7 8 1
9 10 1
11 12 1
File Format: Each line in the external file represents a single transaction, and contains three
numbers: the id of the account from which the money is being transferred, the id of the account
to which the money is going, and the amount of money. For example the line:
17 6 104
indicates that $104 is being transferred from Account #17 to Account #6.
The test data provided includes transfers with the same from and to account numbers, so make
sure your program will work correctly for these transfers. For example:
5 5 40
Count these as two transactions for the account (one transaction taking money from the account
and one putting money into the account).
My goal is to pass each transaction into the queue, the queue will hold the transaction, the
worker will take the transaction, complete the deposit/withdraw, and update the balance of the
account accordingly. I am required to use BlockingQueue. My problem is that the program is not
running correctly. I need to fix the Bank class, how I start up the Bank in main thread, and also
work on Worker class.
More info:
Details
I recommend a design with four classes—Bank, Account, Transaction, and Worker. Both the
Account and Transactions classes are quite simple.
Account needs to store an id number, the current balance for the account, and the number of
transactions that have occurred on the account. Remember that multiple worker threads may be
accessing an account simultaneously and you must ensure that they cannot corrupt its data. You
may also want to override the toString method to handle printing of account information.
Transaction is a simple class that stores information on each transaction (see below for more
information about each transaction). If you’re careful you can treat the Transaction as
immutable. This means that you do not have to worry about multiple threads accessing it.
Remember an immutable object’s values never change, therefore its values are not subject to
corruption in a concurrent environment.
The Bank class maintains a list of accounts and the BlockingQueue used to communicate
between the main thread and the worker threads. The Bank is also responsible for starting up the
worker threads, reading transactions from the file, and printing out all the account values when
everything is done. Note: make sure you start up all the worker threads before reading the
tr.
The program will read the file like this, java homework6Bank sma.pdf
1. The program will read the file like this,
> java homework6/Bank small.txt 4
acct:0 bal:999 trans:1
acct:1 bal:1001 trans:1
acct:2 bal:999 trans:1
acct:3 bal:1001 trans:1
acct:4 bal:999 trans:1
acct:5 bal:1001 trans:1
acct:6 bal:999 trans:1
acct:7 bal:1001 trans:1
acct:8 bal:999 trans:1
acct:9 bal:1001 trans:1
acct:10 bal:999 trans:1
acct:11 bal:1001 trans:1
acct:12 bal:999 trans:1
acct:13 bal:1001 trans:1
acct:14 bal:999 trans:1
acct:15 bal:1001 trans:1
acct:16 bal:999 trans:1
acct:17 bal:1001 trans:1
acct:18 bal:999 trans:1
acct:19 bal:1001 trans:1
Each text file looks something like:
1 2 1
3 4 1
5 6 1
7 8 1
9 10 1
11 12 1
File Format: Each line in the external file represents a single transaction, and contains three
numbers: the id of the account from which the money is being transferred, the id of the account
to which the money is going, and the amount of money. For example the line:
17 6 104
indicates that $104 is being transferred from Account #17 to Account #6.
The test data provided includes transfers with the same from and to account numbers, so make
2. sure your program will work correctly for these transfers. For example:
5 5 40
Count these as two transactions for the account (one transaction taking money from the account
and one putting money into the account).
My goal is to pass each transaction into the queue, the queue will hold the transaction, the
worker will take the transaction, complete the deposit/withdraw, and update the balance of the
account accordingly. I am required to use BlockingQueue. My problem is that the program is not
running correctly. I need to fix the Bank class, how I start up the Bank in main thread, and also
work on Worker class.
More info:
Details
I recommend a design with four classes—Bank, Account, Transaction, and Worker. Both the
Account and Transactions classes are quite simple.
Account needs to store an id number, the current balance for the account, and the number of
transactions that have occurred on the account. Remember that multiple worker threads may be
accessing an account simultaneously and you must ensure that they cannot corrupt its data. You
may also want to override the toString method to handle printing of account information.
Transaction is a simple class that stores information on each transaction (see below for more
information about each transaction). If you’re careful you can treat the Transaction as
immutable. This means that you do not have to worry about multiple threads accessing it.
Remember an immutable object’s values never change, therefore its values are not subject to
corruption in a concurrent environment.
The Bank class maintains a list of accounts and the BlockingQueue used to communicate
between the main thread and the worker threads. The Bank is also responsible for starting up the
worker threads, reading transactions from the file, and printing out all the account values when
everything is done. Note: make sure you start up all the worker threads before reading the
transactions from the file.
I recommend making the Worker class is an inner class of the Bank class. This way it gets easy
access to the list of accounts and the queue used for communication. Workers should check the
queue for transactions. If they find a transaction they should process it. If the queue is empty,
they will wait for the Bank class to read in another transaction (you’ll get this behavior for free
by using a BlockingQueue). Workers terminate when all the transactions have been processed.
package Problem1;
public class Account {
private int id;
private int balance;
3. private int numoft;
public Account(int id, int balance, int numberOfTransactions)
{
this.id = id;
this.balance = 1000;
this.numoft = numberOfTransactions;
}
public int getBalance()
{
return balance;
}
public int getAccountNumber()
{
return id;
}
public int getNumOfTransactions()
{
return numoft;
}
public void deposite(int amount)
{
this.balance = this.balance + amount;
}
public void withdrawl(int amount)
{
this.balance = this.balance - amount;
}
public int addNumOfTrans(int amount)
{
return this.numoft = this.numoft + amount;
}
4. public String toString()
{
return "acct:" + id + " bal:" + balance + " trans:" + numoft + " ";
}
}
_________________________________________
package Problem1;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/*
* Transaction class does the calculation job
*/
public class Transaction {
//private static File filename = new File("test2.txt");
// there can be two transactions, <--- goes to worker
private int accountTo;
private int accountFrom;
private int amount;
public Transaction(int accountTo, int accountFrom, int amount)
{
this.accountTo = accountTo;
this.accountFrom = accountFrom;
this.amount = amount;
}
public int getAccount1()
{
return accountTo;
}
public int getAccount2()
{
5. return accountFrom;
}
public int getTransferAmount()
{
return amount;
}
public String toString()
{
return accountTo + " " + accountFrom + " " + amount;
}
}
___________________________________
package Problem1;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/*
* Bank would read the file
*/
public class Bank implements Runnable {
private ArrayList accounts; // the arraylist that has all the
// account
private ArrayList accountid; // the arraylist that hold all the
// account id so i can find
private ArrayList listOfT; // list of transaction
private int worker;
6. private File filename;
private BlockingQueue queue;
private final Transaction nullTrans = new Transaction(-1, 0, 0);
private int numThread;
public Bank(int numThread) {
this.numThread = numThread;
accounts = new ArrayList();
accountid = new ArrayList();
listOfT = new ArrayList();
}
public void addAccount(Account a) {
accounts.add(a);
}
// public Account replaceAccount(Account e)
// {
// return this.accounts.get(index) = e;
// }
public boolean checkAccounts(int id) {
for (Account b : accounts) {
if (b.getAccountNumber() == id) {
return true; // account exist
}
}
return false;
}
public Account find(int accountNumber) {
for (Account a : accounts) {
if (a.getAccountNumber() == accountNumber) // Found a match
return a;
}
// No match in the entire array list
throw new IllegalArgumentException("Account number " + accountNumber + " was not
found in the bank");
}
public String toString() {
7. for (Account a : accounts) {
// System.out.println("acct:" + a.getAccountNumber() + " bal:" +
// a.getBalance() + " trans:" + a.getNumOfTransactions());
return "acct:" + a.getAccountNumber() + " bal:" + a.getBalance() + " trans:" +
a.getNumOfTransactions();
}
return null;
}
public void readTransaction(Scanner in) {
int a1;
int a2;
int balance;
while (in.hasNext()) {
a1 = in.nextInt();
a2 = in.nextInt();
balance = in.nextInt();
if (!checkAccounts(a1)) {
Account newAccount = new Account(a1, 1000, 0);
addAccount(newAccount);
accountid.add(a1);
}
if (!checkAccounts(a2)) {
Account newAccount = new Account(a2, 1000, 0);
addAccount(newAccount);
accountid.add(a2);
}
listOfT.add(new Transaction(a1, a2, balance));
}
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
queue.put(listOfT.get(0));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
8. e.printStackTrace();
}
}
// main thread
public static void main(String[] args) throws FileNotFoundException {
// start the worker's thread before transaction
//int thread = Integer.parseInt(args[1]);
// BlockingQueue q = new ArrayBlockingQueue(50);
int thread = 4; // numthread
Bank myBank = new Bank(thread);
myBank.queue = new ArrayBlockingQueue(50);
new Thread(myBank).start();
for (int i = 0; i < myBank.queue.size(); i++)
{
myBank.new Worker().start();
}
myBank.filename = new File("test2.txt");
Scanner in = new Scanner(myBank.filename);
myBank.readTransaction(in);
System.out.println(myBank.accounts);
// reading transactions
}
class Worker extends Thread {
// receive the transaction, add the number of transaction amount into
// queue
// queue will hold the transaction action
// find the from account and to account, run() method
// get the money
public void run() {
// TODO Auto-generated method stub
while (queue != nullTrans) {
try {
takeTransaction(queue.take());
} catch (InterruptedException e) {
9. // TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void takeTransaction(Transaction t)
{
int a1;
int a2;
int balance;
a1 = t.getAccount1();
a2 = t.getAccount2();
balance = t.getTransferAmount();
Account account1 = find(a1);
Account account2 = find(a2);
account1.withdrawl(balance);
account2.deposite(balance);
account1.addNumOfTrans(1);
account2.addNumOfTrans(1);
accounts.remove(a1);
addAccount(account1);
accounts.remove(a2);
addAccount(account2);
}
}
}
// you put stuff in queue from bank,
// the worker receive it and do the transaction
/*
*
*/
Solution
public class Account {
10. private int id;
private int balance;
private int numoft;
public Account(int id, int balance, int numberOfTransactions)
{
this.id = id;
this.balance = 1000;
this.numoft = numberOfTransactions;
}
public int getBalance()
{
return balance;
}
public int getAccountNumber()
{
return id;
}
public int getNumOfTransactions()
{
return numoft;
}
public void deposite(int amount)
{
this.balance = this.balance + amount;
}
public void withdrawl(int amount)
{
this.balance = this.balance - amount;
}
public int addNumOfTrans(int amount)
{
11. return this.numoft = this.numoft + amount;
}
public String toString()
{
return "acct:" + id + " bal:" + balance + " trans:" + numoft + " ";
}
}
_________________________________________
package Problem1;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/*
* Transaction class does the calculation job
*/
public class Transaction {
//private static File filename = new File("test2.txt");
// there can be two transactions, <--- goes to worker
private int accountTo;
private int accountFrom;
private int amount;
public Transaction(int accountTo, int accountFrom, int amount)
{
this.accountTo = accountTo;
this.accountFrom = accountFrom;
this.amount = amount;
}
public int getAccount1()
{
return accountTo;
}
12. public int getAccount2()
{
return accountFrom;
}
public int getTransferAmount()
{
return amount;
}
public String toString()
{
return accountTo + " " + accountFrom + " " + amount;
}
}
___________________________________
package Problem1;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/*
* Bank would read the file
*/
public class Bank implements Runnable {
private ArrayList accounts; // the arraylist that has all the
// account
private ArrayList accountid; // the arraylist that hold all the
// account id so i can find
13. private ArrayList listOfT; // list of transaction
private int worker;
private File filename;
private BlockingQueue queue;
private final Transaction nullTrans = new Transaction(-1, 0, 0);
private int numThread;
public Bank(int numThread) {
this.numThread = numThread;
accounts = new ArrayList();
accountid = new ArrayList();
listOfT = new ArrayList();
}
public void addAccount(Account a) {
accounts.add(a);
}
// public Account replaceAccount(Account e)
// {
// return this.accounts.get(index) = e;
// }
public boolean checkAccounts(int id) {
for (Account b : accounts) {
if (b.getAccountNumber() == id) {
return true; // account exist
}
}
return false;
}
public Account find(int accountNumber) {
for (Account a : accounts) {
if (a.getAccountNumber() == accountNumber) // Found a match
return a;
}
// No match in the entire array list
throw new IllegalArgumentException("Account number " + accountNumber + " was not
found in the bank");
14. }
public String toString() {
for (Account a : accounts) {
// System.out.println("acct:" + a.getAccountNumber() + " bal:" +
// a.getBalance() + " trans:" + a.getNumOfTransactions());
return "acct:" + a.getAccountNumber() + " bal:" + a.getBalance() + " trans:" +
a.getNumOfTransactions();
}
return null;
}
public void readTransaction(Scanner in) {
int a1;
int a2;
int balance;
while (in.hasNext()) {
a1 = in.nextInt();
a2 = in.nextInt();
balance = in.nextInt();
if (!checkAccounts(a1)) {
Account newAccount = new Account(a1, 1000, 0);
addAccount(newAccount);
accountid.add(a1);
}
if (!checkAccounts(a2)) {
Account newAccount = new Account(a2, 1000, 0);
addAccount(newAccount);
accountid.add(a2);
}
listOfT.add(new Transaction(a1, a2, balance));
}
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
queue.put(listOfT.get(0));
15. } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// main thread
public static void main(String[] args) throws FileNotFoundException {
// start the worker's thread before transaction
//int thread = Integer.parseInt(args[1]);
// BlockingQueue q = new ArrayBlockingQueue(50);
int thread = 4; // numthread
Bank myBank = new Bank(thread);
myBank.queue = new ArrayBlockingQueue(50);
new Thread(myBank).start();
for (int i = 0; i < myBank.queue.size(); i++)
{
myBank.new Worker().start();
}
myBank.filename = new File("test2.txt");
Scanner in = new Scanner(myBank.filename);
myBank.readTransaction(in);
System.out.println(myBank.accounts);
// reading transactions
}
class Worker extends Thread {
// receive the transaction, add the number of transaction amount into
// queue
// queue will hold the transaction action
// find the from account and to account, run() method
// get the money
public void run() {
// TODO Auto-generated method stub
while (queue != nullTrans) {
try {