Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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
bgColor#FFcccc
public class Racer {
  double currentSpeed;
  double distanceTraveled; 

  public double getCurrentSpeed() {
    return currentSpeed;
  }

  public double getDistance() {
    return distanceTraveled;
  }
}

...

Code Block
bgColor#FFcccc
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
bgColor#ccccff
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);
    }
  }
}

...