import java.util.*;
@author
class SharedAccountBio {
public static void run(int msPerYear) {
final Account account = new Account("MyChecking", 0);
final int yearLength = msPerYear; final int monthLength = yearLength/12;
final int weekLength = yearLength/52;
final long yearStart = System.currentTimeMillis();
final long yearEnd = yearStart + yearLength;
Thread billee = new Thread("Billee") {
public void run() {
int salary = 300;
for (int week = 1; week <= 52; week++) {
sleepTo(yearStart + week * weekLength);
account.deposit(salary);
}
}};
Thread lordy = new Thread("Lordy") {
public void run() {
final int rent = 1000; final int penalty = 10;
final Collection outstandingCollectors =
Collections.synchronizedCollection(new LinkedList());
int collectorCount = 0;
for (int month = 1; month <= 12; month++) {
try { account.withdraw(rent); }
catch (IllegalArgumentException overdraft) {
Thread collector = new Thread("Collector"+(++collectorCount)) {
int due = rent + penalty;
long startDate = System.currentTimeMillis();
int week = 0;
public void run() {
while (System.currentTimeMillis() <= yearEnd) {
try {
account.withdraw(due);
break;
} catch (IllegalArgumentException overdraft2) {
week++; due += penalty;
sleepTo(startDate + week * weekLength);
}
}
outstandingCollectors.remove(this);
return;
}};
outstandingCollectors.add(collector);
collector.start(); Thread.yield();
}
sleepTo(yearStart + month * monthLength);
}
return;
}};
billee.start();
lordy.start();
try { billee.join(); lordy.join(); } catch (InterruptedException e) {}
System.out.println("Billee's final balance: "+ account.getBalance());
return;
}
static void sleepTo(long wakeupTime) {
long now = System.currentTimeMillis();
try { Thread.sleep(wakeupTime - now); }
catch (InterruptedException e) {}
catch (IllegalArgumentException e) { } }
public static void main(String[] parameters) {
int parameter =
Integer.parseInt(parameters.length == 0 ? "12" : parameters[0]);
run(1000 * parameter);
}
}
class Account {
private String myName;
private int myBalance;
public Account(String name, int initBalance) {
myName = name;
myBalance = initBalance;
}
public synchronized int getBalance() {
return myBalance;
}
public synchronized void deposit(int amount) {
myBalance += amount;
}
public synchronized void withdraw(int amount) {
if (amount <= myBalance)
myBalance -= amount;
else
throw new IllegalArgumentException("Overdraft");
}
public String toString() {
return "Account(name="+myName+", balance="+myBalance+")"; }
}