// This file contains excerpts from the textbook Concrete // Abstractions: An Introduction to Computer Science Using Scheme, by // Max Hailperin, Barbara Kaiser, and Karl Knight, Copyright (c) 1998 // by the authors. Full text is available for free at // http://www.gustavus.edu/+max/concrete-abstractions.html // Warning: this class is missing some necessary synchronized keywords, // because it is intended as an exercise in debugging concurrent programs. public class CompoundingThread extends Thread { private boolean enabled; private double initial, current, multiplier; private int year; private Compounder c; private java.text.NumberFormat fmt; // Invariant: // (1) current = initial * (multiplier raised to the // year power) // (2) year also specifies how many lines of output c has // gotten since it was last cleared, corresponding to // years from 0 up through year-1. public CompoundingThread(Compounder comp){ c = comp; fmt = java.text.NumberFormat.getCurrencyInstance(); } synchronized private void waitUntilEnabled() throws InterruptedException { while(!enabled){ wait(); } } synchronized public void disable(){ enabled = false; } synchronized public void enable(){ enabled = true; notify(); } public void run(){ try{ while(true){ Thread.sleep(1000); waitUntilEnabled(); doYear(); } } catch(InterruptedException e){ // ignore, but stop running } } private void doYear(){ c.outputLine("After " + year + " years, " +fmt.format(current)); year++; current *= multiplier; } public void setInitialAmount(double amount){ initial = amount; initialize(); } public void setInterestRate(double rate){ // note that a rate of 5% (e.g.) would be .05, *not* 5 multiplier = 1 + rate; initialize(); } private void initialize(){ current = initial; year = 0; c.clearOutput(); } }