...
This noncompliant code example consists of an application to monitor a sports race. Each racer is asociated with a dedicated object instance of class Racer
:
Code Block | ||
---|---|---|
| ||
public class Racer { double currentSpeed; double distanceTraveled; public double getCurrentSpeed() { return currentSpeed; } public double getDistance() { return distanceTraveled; } } |
...
Code Block | ||
---|---|---|
| ||
public class Race { static final int MAX = 20; private static final Racer[] racers = new Racer[MAX]; public Race() { for (int i = 0; i < MAX; i++// For thread-safety, caller must relinquich any references to racers public Race(Racer[] racers) { racers[i]this.racers = new Racer(/* initialize racer */)racers; } } double getAverageCurrentSpeed() { return averageCurrentSpeedCalculator(0, 0.0); } double averageCurrentSpeedCalculator(int i, double currentSpeed) { // Acquires locks in increasing order if (i > MAXracers.length - 1) { return currentSpeed / MAXracers.length; } synchronized(racers[i]) { currentSpeed += racers[i].getCurrentSpeed(); return averageCurrentSpeedCalculator(++i, currentSpeed); } } double getAverageDistance() { return averageDistanceCalculator(MAXracers.length - 1, 0.0); } double averageDistanceCalculator(int i, double distance) { // Acquires locks in decreasing order if (i <= -1) { return distance / MAXracers.length; } synchronized(racers[i]) { distance += racers[i].getDistance(); return averageDistanceCalculator(--i, distance); } } } |
Consequently, the statics statistics reported by the methods are accurate at the time the methods actually return their results.
...
Code Block | ||
---|---|---|
| ||
public class Race { double getAverageCurrentSpeed() { return averageCurrentSpeedCalculator(0, 0.0); } double averageCurrentSpeedCalculator(int i, double currentSpeed) { // Acquires locks in increasing order if (i > MAXracers.length - 1) { return currentSpeed / MAXracers.length; } synchronized(racers[i]) { currentSpeed += racers[i].getCurrentSpeed(); return averageCurrentSpeedCalculator(++i, currentSpeed); } } double getAverageDistance() { return averageDistanceCalculator(0, 0.0); } double averageDistanceCalculator(int i, double distance) { // Acquires locks in increasing order if (i > MAXracers.length - 1) { return distance / MAXracers.length; } synchronized(racers[i]) { distance += racers[i].getDistance(); return averageDistanceCalculator(++i, distance); } } } |
...