Advertisement
Guest User

Untitled

a guest
Nov 8th, 2015
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.37 KB | None | 0 0
  1. import java.math.BigDecimal;
  2. import java.util.ArrayList;
  3. import java.util.concurrent.TimeUnit;
  4.  
  5. public class BankSimApp {
  6.     public static void main(String[] args) {
  7.         BankAccount account = new BankAccount(0.0, "1254 12 1245 45646546547");
  8.         int operationCounter = 0;
  9.  
  10.         while(true) {
  11.             (new BankOperation(operationCounter++, account, OperationType.Deposit, 600.6, "Paysheet", 4)).start();
  12.             (new BankOperation(operationCounter++, account, OperationType.Reintegrate, 400.0, "Mortgage", 4, PostponedType.AlwaysWhenDeposit)).start();
  13.             (new BankOperation(operationCounter++, account, OperationType.Reintegrate, 40.0, "Electricity", 4, PostponedType.Once)).start();
  14.             (new BankOperation(operationCounter++, account, OperationType.Reintegrate, 30.0, "Water", 4, PostponedType.Once)).start();
  15.             (new BankOperation(operationCounter++, account, OperationType.Reintegrate, 50.0, "Purchases", 2)).start();
  16.             (new BankOperation(operationCounter++, account, OperationType.Reintegrate, 20.0, "Cash withdrawal", 2)).start();
  17.             (new BankOperation(operationCounter++, account, OperationType.Reintegrate, 100.0, "Life insurance", 4, PostponedType.AlwaysPeriod)).start();
  18.  
  19.             try {
  20.                 TimeUnit.SECONDS.sleep(4);
  21.             } catch (InterruptedException e) {
  22.             }
  23.         }
  24.     }
  25. }
  26.  
  27. class BankOperation extends Thread {
  28.     private final OperationType operationType;
  29.     private final double amount;
  30.     private final String concept;
  31.     private final PostponedType postponedType;
  32.     private final BankAccount account;
  33.     private final int waitToPerformOperation;
  34.     private final int operationId;
  35.  
  36.     public BankOperation(int operationId, BankAccount account,OperationType operationType, double amount, String concept, int waitToPerformOperation, PostponedType postponedType) {
  37.         this.operationType = operationType;
  38.         this.amount = amount;
  39.         this.concept = concept;
  40.         this.postponedType = postponedType;
  41.         this.account = account;
  42.         this.waitToPerformOperation = waitToPerformOperation;
  43.         this.operationId = operationId;
  44.     }
  45.  
  46.     public BankOperation(int operationId, BankAccount account,OperationType operationType, double amount, String concept, int waitToPerformOperation) {
  47.         this(operationId, account, operationType, amount, concept, waitToPerformOperation, PostponedType.Deny);
  48.     }
  49.  
  50.     public void run() {
  51.         boolean tryAgain = true;
  52.         boolean isPosponedOperation = false;
  53.         final StringBuilder message = new StringBuilder();
  54.         int retryCounter = 0;
  55.  
  56.         BankMovement bankMovement = null;
  57.  
  58.         try {
  59.             TimeUnit.SECONDS.sleep(this.waitToPerformOperation);
  60.         } catch (InterruptedException e) {
  61.             e.printStackTrace();
  62.         }
  63.  
  64.         while(tryAgain) {
  65.             message.delete(0, message.length());
  66.  
  67.             if(this.operationType == OperationType.Reintegrate) {
  68.                 if((bankMovement = this.account.reintegrate(this.amount, this.concept)) == null) {
  69.                     message.append("[").append(this.operationId).append(": ").append(this.concept).append("] ");
  70.  
  71.                     if(this.postponedType == PostponedType.Deny) {
  72.                         message.append("There is insufficient balance to perform this operation. Please try again later.");
  73.                         tryAgain = false;
  74.                     } else if(this.postponedType == PostponedType.AlwaysPeriod) {
  75.                         message.append("There is insufficient balance to perform this operation. This operation will be postponed for a period of time");
  76.  
  77.                         try {
  78.                             TimeUnit.SECONDS.sleep(this.waitToPerformOperation / 2);
  79.                         } catch (InterruptedException e) {
  80.                             Thread.currentThread().interrupt();
  81.                         }
  82.                     } else if(this.postponedType == PostponedType.AlwaysWhenDeposit) {
  83.                         message.append("There is insufficient balance to perform this operation. This operation will be postponed until deposit is made.");
  84.  
  85.                         this.account.waitUnitDepositIsMade();
  86.                     } else if(this.postponedType == PostponedType.Once) {
  87.                         if(retryCounter <= 0) {
  88.                             message.append("There is insufficient balance to perform this operation. " + (retryCounter <= 0 ? "This operation will be postponed for a period of time. (1 try)" : " The recive is returned"));
  89.  
  90.                             try {
  91.                                 TimeUnit.SECONDS.sleep(this.waitToPerformOperation / 2);
  92.                             } catch (InterruptedException e) {
  93.                                 Thread.currentThread().interrupt();
  94.                             }
  95.                         } else {
  96.                             message.append("There is insufficient balance to perform this operation. This receve is returned.");
  97.                             tryAgain = false;
  98.                         }
  99.                     }
  100.  
  101.                     Display.getInstance().err(message.toString());
  102.  
  103.                     retryCounter++;
  104.                     isPosponedOperation = true;
  105.                 } else {
  106.  
  107.                     message.append("[").append(this.operationId).append("]: ").append(bankMovement).append((isPosponedOperation) ? " (Postponed operation)" : "");
  108.  
  109.                     Display.getInstance().out(message.toString());
  110.                     tryAgain = false;
  111.                 }
  112.             } else {
  113.                 bankMovement = this.account.deposit(this.amount, this.concept);
  114.  
  115.                 message.append('[').append(this.operationId).append("]: ").append(bankMovement);
  116.                 Display.getInstance().out(message.toString());
  117.                 tryAgain = false;
  118.             }
  119.         }
  120.     }
  121. }
  122.  
  123. class BankAccount {
  124.     private double balance; // Guarded by this
  125.     private int movementCounter; // Guarded by this
  126.     private final ArrayList<BankMovement> movements; // Guarded by this
  127.  
  128.     private String accountNumber;
  129.     private final Object depositLock = new Object();
  130.  
  131.     public BankAccount(final double initialBalance, String accountNumber) {
  132.         this.balance = initialBalance;
  133.         this.accountNumber = accountNumber;
  134.         this.movementCounter = 0;
  135.         this.movements = new ArrayList<>();
  136.     }
  137.  
  138.     public synchronized int getNextMovementId() {
  139.         return ++this.movementCounter;
  140.     }
  141.  
  142.     public void waitUnitDepositIsMade() {
  143.         synchronized (this.depositLock) {
  144.             try {
  145.                 this.depositLock.wait();
  146.             } catch (InterruptedException e) {
  147.                 e.printStackTrace();
  148.             }
  149.         }
  150.     }
  151.  
  152.     public synchronized double getCurrentBalance() {
  153.         return this.balance;
  154.     }
  155.  
  156.     public BankMovement deposit(double amount, String concept) {
  157.         BankMovement bankMovement = null;
  158.  
  159.         synchronized (this) {
  160.             this.balance += amount;
  161.  
  162.             bankMovement = new BankMovement(this.getNextMovementId(), concept, this.balance, amount);
  163.             this.movements.add(bankMovement);
  164.         }
  165.  
  166.         synchronized (this.depositLock) {
  167.             this.depositLock.notifyAll();
  168.         }
  169.  
  170.         return bankMovement;
  171.     }
  172.  
  173.     public synchronized BankMovement reintegrate(double amount, String concept) {
  174.         if((this.balance - amount) < 0.0) {
  175.             return null;
  176.         }
  177.  
  178.         this.balance -= amount;
  179.  
  180.         BankMovement bankMovement = new BankMovement(this.getNextMovementId(), concept, this.balance, -(amount));
  181.         this.movements.add(bankMovement);
  182.  
  183.         return bankMovement;
  184.     }
  185. }
  186.  
  187. class BankMovement {
  188.     private final int movementId;
  189.     private final String concept;
  190.     private final double balance;
  191.     private final double amount;
  192.  
  193.     public BankMovement(int movementId, String concept, double balance, double amount) {
  194.         this.movementId = movementId;
  195.         this.concept = concept;
  196.         this.balance = balance;
  197.         this.amount = amount;
  198.     }
  199.  
  200.     private static BigDecimal truncateDecimal(double x, int numberofDecimals) {
  201.         return (x > 0) ? new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_FLOOR) :
  202.                         new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_CEILING);
  203.     }
  204.  
  205.     @Override
  206.     public String toString() {
  207.         StringBuilder result = new StringBuilder();
  208.  
  209.         result.append("#").append(this.movementId).append('\t').append(this.concept).append('\t').append(this.truncateDecimal(this.amount, 2).toString())
  210.                 .append('\t').append(this.truncateDecimal(this.balance, 2).toString());
  211.  
  212.         return result.toString();
  213.     }
  214. }
  215.  
  216. class Display {
  217.     private final static Display instance = new Display();
  218.  
  219.     private Display() {}
  220.  
  221.     public synchronized void out(String str) {
  222.         System.out.println(str);
  223.         System.out.flush();
  224.     }
  225.  
  226.     public synchronized void err(String str) {
  227.         System.err.println(str);
  228.         System.err.flush();
  229.     }
  230.  
  231.     public static Display getInstance() {
  232.         return instance;
  233.     }
  234. }
  235.  
  236. enum OperationType {
  237.     Reintegrate, Deposit
  238. }
  239.  
  240. enum PostponedType {
  241.     Deny, Once, AlwaysPeriod, AlwaysWhenDeposit
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement