Skip to content

Instantly share code, notes, and snippets.

@VincentTatan
Created November 26, 2015 01:11
Show Gist options
  • Save VincentTatan/0be829370ed6fbc742e0 to your computer and use it in GitHub Desktop.
Save VincentTatan/0be829370ed6fbc742e0 to your computer and use it in GitHub Desktop.
package aa.race;
import aa.StopWatch;
import java.util.Random;
import java.util.concurrent.locks.*;
/**
*
* This is testing code with different scenarios to test the Account class.
* Only make changes to enable the right scenario.
*
*/
public class BankWeek10 implements Runnable
{
/////////////////////////////////////////////////////////
//
// Run Parameters - no need to change these.
//
/////////////////////////////////////////////////////////
private static int numTranx = 5000; //transactions
private static int amountEachTransfer = 2; //amount of every transaction
//4 transaction threads
//2 report threads
private static int numThreads = 6;
/////////////////////////////////////////////////////////
//
// Data Structures and constants -- Do NOT change these.
//
/////////////////////////////////////////////////////////
final static int NumberOfAccounts = 20; //Max number of different accounts
//3 Scenarios -- just A to B; A to B and B to A; A,B,C,D,... with all permutations.
final static int ONLY_A_TO_B = 1;
final static int A_TO_B_AND_B_TO_A = 2;
final static int ALL_PERMUTATIONS_A_B_C_D = 12;
final static int EVERYTHING = NumberOfAccounts;
final static String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()"; //Account names
static int allowed_transfers = ONLY_A_TO_B; //user choice of scenario
/////////////////////////////////////////////////////////
//
// Account structures -- Do NOT change these.
//
/////////////////////////////////////////////////////////
private static Account[] accounts = new Account[NumberOfAccounts];
private static float starting = 0; //Expected final sum of account values
private final int id;
private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
/**
* Set up so that one thread runs reports, while the rest are making transactions.
*/
private void runReports()
{
try
{
lock.readLock().lock();
for (int i = 0; i < 10; i++)
{
int total = report();
System.out.println("Reporting Thread #" + id + " current total of accounts : "+ total);
Thread.sleep(100); //wait 100ms before next report
}
lock.readLock().unlock();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
private static int report()
{
int total = 0;
//----------------------------- WEEK 10 ---------------------
// Is this a critical section ?
for (Account a : accounts)
{
if (a != null)
{
total += a.getBalance();
}
}
//----------------------------- WEEK 10 ---------------------
return total;
}
public BankWeek10(int i)
{
id = i;
}
public static void main(String[] args)
{
//
// For week 10 exercise, we use option 1 again, and on disk
//
int Exercise_Part = 1;
//Get User choice of scenario
// Scanner sc = new Scanner(System.in);
// System.out.print("0: Random transfers among many accounts (all permutations possible)\n1: Transfers only from A to B\n2: Transfers from A to B and from B to A\nChoose which part of exercise you are doing (0,1,2): ");
// Exercise_Part = sc.nextInt();
// sc.nextLine();
String[] alphabetArray = alphabet.split("(?!(^|$))");
for (int i = 0; i < alphabetArray.length; i++){
alphabetArray[i] = alphabetArray[i];
}
switch (Exercise_Part)
{
case 0:
//All accounts to All accounts. We want this to be faster with Parallelism.
for (int i = 0; i<NumberOfAccounts; i++){
accounts[i] = new Account(10000, alphabetArray[i], false);
}
allowed_transfers = EVERYTHING;
starting = 10000*NumberOfAccounts;
break;
case 1:
//PART I -- A->B only, start 10k each
for (int i = 0; i<2; i++){
accounts[i] = new Account(10000, alphabetArray[i], true);
}
allowed_transfers = ONLY_A_TO_B;
starting = 20000;
numThreads = 4;
break;
case 2:
//PART II -- A->B concurrent with A<-B, start 10 each
for (int i = 0; i<2; i++){
accounts[i] = new Account(10, alphabetArray[i], false);
}
allowed_transfers = A_TO_B_AND_B_TO_A;
starting = 20;
break;
}
//Get User choice of number of threads to use
// System.out.print("Enter number of threads to use (integer > 0): ");
// Scanner sc = new Scanner(System.in);
System.out.println("Using " + numThreads + " threads.");
// numThreads = 4;
//sc.nextLine();
try
{
System.out.println("Starting total of accounts : "+ starting);
//hold all the transaction threads
StopWatch watch = new StopWatch();
Thread[] threads = new Thread[numThreads];
for (int i =0; i < numThreads; i++)
{
threads[i] = new Thread(new BankWeek10(i));
}
watch.start();
//create and start all the threads
for (int i =0; i < numThreads; i++)
{
threads[i].start();
}
//wait for all threads to end
for (int j =0; j < numThreads; j++)
{ threads[j].join(); }
long elapsedTime = watch.stop(); //HELP!
// System.out.println("Total execution time (ms): " + (elapsedTime) );
// System.out.println();
}
catch (InterruptedException e)
{ e.printStackTrace(); } //To change body of catch statement use File | Settings | File Templates.
finally
{
int total = report();
// System.out.println("Final balance for A = " + accounts[0].getBalance());
// System.out.println("Final balance for B = " + accounts[1].getBalance());
// if (allowed_transfers == ALL_PERMUTATIONS_A_B_C_D)
// {
// System.out.println("Final balance for C = " + accounts[2].getBalance());
// System.out.println("Final balance for D = " + accounts[3].getBalance());
// }
// if (allowed_transfers == EVERYTHING)
// {
//
// for (int i = 2; i < NumberOfAccounts; i++){
//
// System.out.println("Final balance for "+alphabetArray[i]+" = " + accounts[i].getBalance());
// }
//
// }
// These are usually different. In week 9 we explore why, and what we can do about.
System.out.println("Ending total of accounts : "+ total);
}
}
/**
* What the thread does:
* Makes numTranx / numThreads transfers between chosen accounts.
*/
public void run()
{
if (id == 0 || id == 1)
{
runReports();
return;
}
Random r = new Random();
for (int t = 0; t < numTranx / numThreads; t++)
{
if (allowed_transfers < 3){
int from = r.nextInt(allowed_transfers);
if (from == 0)
{
// a.transfer(amountEachTransfer, b);
accounts[from].transfer(amountEachTransfer, accounts[1]); //A transfer to B
}
else if (from == 1)
{
// b.transfer(amountEachTransfer, a);
accounts[from].transfer(amountEachTransfer, accounts[0]); //B transfer to A
}
}
else if (allowed_transfers == 12)
{
int from = r.nextInt(4);
int to = r.nextInt(4);
while (from==to){
to = r.nextInt(4);
}
accounts[from].transfer(amountEachTransfer, accounts[to]);
}
else if (allowed_transfers == NumberOfAccounts){
int from = r.nextInt(NumberOfAccounts);
int to = r.nextInt(NumberOfAccounts);
while (from==to){
to = r.nextInt(NumberOfAccounts);
}
accounts[from].transfer(amountEachTransfer, accounts[to]);
}
}
}
}
Using 4 threads.
Starting total of accounts : 20000.0
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #0 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Reporting Thread #1 current total of accounts : 20000
Ending total of accounts : 20000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment