Initial commit

This commit is contained in:
github-classroom[bot]
2022-03-31 09:49:56 +00:00
commit 5a1de0b8e7
83 changed files with 17003 additions and 0 deletions
@@ -0,0 +1,22 @@
/*
* Gradle build configuration for specific lab module / exercise
* Default declarations can be found in the lab main build configuration (../../gradle.build)
* Declarations in this file extend or override the default values.
*/
// the Java plugin is added by default in the main lab configuration
plugins {
// Apply the application plugin to add support for building a CLI application.
id 'application'
}
description = 'Lab04 AccountTransfer Solution'
dependencies {
}
// Configuration for Application plugin
application {
// Define the main class for the application.
mainClass = 'ch.zhaw.prog2.account.AccountTransferSimulation'
}
@@ -0,0 +1,23 @@
package ch.zhaw.prog2.account;
public class Account {
private final int id;
private int balance = 0;
public Account(int id, int initialAmount) {
this.id = id;
this.balance = initialAmount;
}
public int getId() {
return id;
}
public synchronized int getBalance() {
return balance;
}
public synchronized void transferAmount(int amount) {
this.balance += amount;
}
}
@@ -0,0 +1,67 @@
package ch.zhaw.prog2.account;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class AccountTransferSimulation {
private static final int ITERATIONS = 10000;
public static void main(String[] args) throws InterruptedException {
Account account1 = new Account(1, 10);
Account account2 = new Account(2, 10);
Account account3 = new Account(3, 999999);
System.out.println("Start Balance:");
System.out.println("- Account1 = " + account1.getBalance());
System.out.println("- Account2 = " + account2.getBalance());
System.out.println("- Account3 = " + account3.getBalance());
System.out.println("Summed up balances of all accounts: " +
(account1.getBalance() + account2.getBalance() + account3.getBalance()));
System.out.println("Start of Transaction");
// AccountTransferTask task1 = new AccountTransferTask(account3, account1, 2);
AccountTransferTask task1 = new AccountTransferTask(account1, account3, 2);
AccountTransferTask task2 = new AccountTransferTask(account3, account2, 1);
AccountTransferTask task3 = new AccountTransferTask(account2, account1, 2);
// create ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(8);
// execute transactions on accounts
System.out.println("Submitting...");
for (int count = 0; count < ITERATIONS; count++) {
executor.execute(task1);
executor.execute(task2);
executor.execute(task3);
}
System.out.println("Working...");
executor.shutdown();
// wait for completion
boolean completed = executor.awaitTermination(20, TimeUnit.SECONDS);
if (completed) {
System.out.println("Transactions completed!");
} else {
System.out.println("Transactions timed out!");
executor.shutdownNow();
}
// Print end statistics
System.out.println("Amount transferred (when enough on fromAccount):");
System.out.println("- Task 1 = " + task1.getTotalTransfer());
System.out.println("- Task 2 = " + task2.getTotalTransfer());
System.out.println("- Task 3 = " + task3.getTotalTransfer());
System.out.println("End Balance:");
System.out.println("- Account1 = " + account1.getBalance());
System.out.println("- Account2 = " + account2.getBalance());
System.out.println("- Account3 = " + account3.getBalance());
System.out.println("Summed up balances of all accounts (should be the same as at start): " +
(account1.getBalance() + account2.getBalance() + account3.getBalance()));
}
}
@@ -0,0 +1,58 @@
package ch.zhaw.prog2.account;
class AccountTransferTask implements Runnable {
private final Account fromAccount;
private final Account toAccount;
private final int amount;
private int totalTransfer = 0;
public AccountTransferTask(Account fromAccount, Account toAccount, int amount) {
this.fromAccount = fromAccount;
this.toAccount = toAccount;
this.amount = amount;
}
public int getTotalTransfer() {
return this.totalTransfer;
}
@Override
public void run() {
//transfer();
transferDLfree();
}
/* b) ensure no lost updates are happening */
public void transfer() {
synchronized (fromAccount) {
synchronized (toAccount) {
// Account must not be overdrawn
if (fromAccount.getBalance() >= amount) {
fromAccount.transferAmount(-amount);
toAccount.transferAmount(amount);
totalTransfer += amount;
}
}
}
}
/* c) deadlock free using ascending order of IDs */
public void transferDLfree() {
// This implementation is deadlock free using the second possibility
// -> locking of accounts in ascending order of accountID
boolean isLower = fromAccount.getId() < toAccount.getId();
Account lowerAccount = isLower ? fromAccount : toAccount;
Account higherAccount = !isLower ? fromAccount : toAccount;
synchronized (lowerAccount) {
synchronized (higherAccount) {
// Account must not be overdrawn
if (fromAccount.getBalance() >= amount) {
fromAccount.transferAmount(-amount);
toAccount.transferAmount(amount);
totalTransfer += amount;
}
}
}
}
}