...
Code Block |
---|
|
public final class Race {
private final Vector<Racer> racers;
private final Object lock = new Object();
public Race(Vector<Racer> racer) {
racers = (Vector<Racer>) racer.clone();
}
public boolean addRacer(Racer racer){
return racers.add(racer);
}
public boolean removeRacer(Racer racer) {
synchronized(racers.elementAt(racers.indexOf(racer))) {
return racers.remove(racer);
}
}
private double getAverageCurrentSpeed(int i, double currentSpeed) {
if (i > racers.size()) {
return currentSpeed / racers.size();
}
synchronized(racers.elementAt(i)) {
currentSpeed += racers.get(i).getCurrentSpeed();
return getAverageCurrentSpeed(++i, currentSpeed);
}
}
private double getAverageCurrentDistance(int i, double distance) {
if (i > racers.size()) {
return distance / racers.size();
}
synchronized(racers.elementAt(i)) {
distance += racers.get(i).getDistance();
return getAverageCurrentDistance(++i, distance);
}
}
public void getStatisticsAtSomePointInRace() {
synchronized(lock) {
getAverageCurrentSpeed(0, 0.0);
getAverageCurrentDistance(0, 0.0);
}
}
}
|
Noncompliant Code Example
Code Block |
---|
|
public class Book {
private String title;
private double width;
private double weight;
public String getTitle() {
return title;
}
public double getWidth() {
return width;
}
public double getWeight() {
return weight;
}
public Book(String title, double width, double weight) {
this.title = title;
this.width = width;
this.weight = weight;
}
}
public class Bookshelf {
private final Vector<Book> books = new Vector<Book>();
public boolean addBook(Book book) {
// lock on last element to prevent race cond with calculation methods
synchronized(books.lastElement()) {
return books.add(new Book( book.getTitle(), book.getWidth(), book.getWeight()));
}
}
// only one remove can happen at a time
public final synchronized boolean removeBook(String title) {
for (int i = 0; i < books.size(); i++) {
if (books.getTitle().equals( title)) {
// lock on book to prevent race cond with calculation routines
synchronized (books.elementAt(i)) {
return books.remove( i);
}
}
}
return false; // book not on bookshelf
}
private double getTotalWidth(int i, double width) {
if (i > books.size()) {
return width;
}
synchronized (books.elementAt(i)) {
numberOfPages += books.get(i).getWidth();
return getTotalWidth(++i, width);
}
}
private double getTotalWeight(int i, double weight) {
if (i <= -1) {
return weight;
}
synchronized (books.elementAt(i)) {
weight += books.get(i).getWeight();
return getTotalWeight(--i, weight);
}
}
}
|
Risk Assessment
Acquiring and releasing locks in the wrong order may result in deadlocks.
...