...
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);
}
}
}
|
...