avoid deadlocks by letting TrackBasedEstimationWindTrackImpl's getEstimatedWind be unsynchronized

This commit is contained in:
Axel Uhl committed 2011-12-23 17:58:05 +01:00
1 parent 5a7fce5e78
commit 8a0c9befac
3 files changed
+18 -3

No files matched your search

@@ -214,7 +214,10 @@ public interface TrackedRace {
/**
* Determines whether the <code>competitor</code> is sailing on port or starboard tack at the
* <code>timePoint</code> requested.
* <code>timePoint</code> requested. Note that this will have to retrieve information about the wind.
* This, in turn, can lead to the current thread obtaining the monitor of the various wind tracks,
* and, if the {@link WindSource#TRACK_BASED_ESTIMATION} source is used, also the monitors of the
* competitors' GPS tracks.
*/
Tack getTack(Competitor competitor, TimePoint timePoint);
@@ -63,7 +63,7 @@ public class TrackBasedEstimationWindTrackImpl extends WindTrackImpl {
* time point is used instead. If both time points are not known, <code>null</code> is returned immediately.
*/
@Override
public synchronized Wind getEstimatedWind(Position p, TimePoint at) {
public Wind getEstimatedWind(Position p, TimePoint at) {
Wind result = null;
TimePoint adjustedAt;
TimePoint raceStartTimePoint = trackedRace.getStart();
@@ -88,7 +88,9 @@ public class TrackBasedEstimationWindTrackImpl extends WindTrackImpl {
}
}
if (adjustedAt != null) {
result = super.getEstimatedWind(p, adjustedAt);
// we can use the unsynchronized version here because our getInternalFixes() method operates
// only on a virtual sequence of wind fixes where no concurrency issues have to be observed
result = getEstimatedWindUnsynchronized(p, adjustedAt);
}
return result;
}
@@ -107,6 +107,16 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
*/
@Override
public synchronized Wind getEstimatedWind(Position p, TimePoint at) {
return getEstimatedWindUnsynchronized(p, at);
}
/**
* This method implements the functionality of the {@link #getEstimatedWind(Position, TimePoint)} interface
* method. However, not being <code>synchronized</code>, it does not obtain this object's monitor. Subclasses
* may use this carefully if they can guarantee there are no concurrency issues with the internal fixes
* while iterating over the result of {@link #getInternalFixes()}.
*/
protected Wind getEstimatedWindUnsynchronized(Position p, TimePoint at) {
DummyWind atTimed = new DummyWind(at);
NavigableSet<Wind> beforeSet = getInternalFixes().headSet(atTimed, /* inclusive */ true);
NavigableSet<Wind> afterSet = getInternalFixes().tailSet(atTimed, /* inclusive */ true);