mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-21 11:40:01 +00:00
moved Util.lock to new class LockUtil which is not in domain.common and hence doesn't hurt the GWT build
This commit is contained in:
1 parent
f82b87f87d
commit
45cb1db0f5
7 files changed
+61
-55
No files matched your search
@@ -4,42 +4,8 @@ import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Util {
|
||||
private static final int NUMBER_OF_SECONDS_TO_WAIT_FOR_LOCK = 5;
|
||||
private static final Logger logger = Logger.getLogger(Util.class.getName());
|
||||
|
||||
/**
|
||||
* Bug <a href="http://bugs.sun.com/view_bug.do?bug_id=6822370">http://bugs.sun.com/view_bug.do?bug_id=6822370</a> seems
|
||||
* dangerous, particularly if it happens in a <code>LiveLeaderboardUpdater</code> thread. Even though the bug is reported to
|
||||
* have been fixed in JDK 7(b79) we should be careful. This method tries to acquire a lock, allowing for five seconds to pass.
|
||||
* After five seconds and not having retrieved the lock, tries again until the lock has been acquired.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public static void lock(Lock lock) {
|
||||
boolean locked = false;
|
||||
boolean interrupted = false;
|
||||
while (!locked) {
|
||||
try {
|
||||
locked = lock.tryLock(NUMBER_OF_SECONDS_TO_WAIT_FOR_LOCK, TimeUnit.SECONDS);
|
||||
if (!locked) {
|
||||
logger.info("Couldn't acquire lock in "+NUMBER_OF_SECONDS_TO_WAIT_FOR_LOCK+"s. Trying again...");
|
||||
}
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
interrupted = true;
|
||||
}
|
||||
}
|
||||
if (interrupted) {
|
||||
// re-assert interrupt state that occurred while we
|
||||
// were acquiring the lock
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all elements from <code>what</code> to <code>addTo</code> and returns <code>addTo</code> for chained use.
|
||||
*/
|
||||
|
||||
@@ -24,8 +24,8 @@ import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.impl.NamedImpl;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.util.CourseAsWaypointList;
|
||||
import com.sap.sailing.util.impl.LockUtil;
|
||||
|
||||
import difflib.DiffUtils;
|
||||
import difflib.Patch;
|
||||
@@ -69,7 +69,7 @@ public class CourseImpl extends NamedImpl implements Course {
|
||||
|
||||
@Override
|
||||
public void lockForRead() {
|
||||
Util.lock(lock.readLock());
|
||||
LockUtil.lock(lock.readLock());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,7 +109,7 @@ public class CourseImpl extends NamedImpl implements Course {
|
||||
|
||||
@Override
|
||||
public void addWaypoint(int zeroBasedPosition, Waypoint waypointToAdd) {
|
||||
Util.lock(lock.writeLock());
|
||||
LockUtil.lock(lock.writeLock());
|
||||
try {
|
||||
waypoints.add(zeroBasedPosition, waypointToAdd);
|
||||
Map<Waypoint, Integer> updatesToWaypointIndexes = new HashMap<Waypoint, Integer>();
|
||||
@@ -139,7 +139,7 @@ public class CourseImpl extends NamedImpl implements Course {
|
||||
public void removeWaypoint(int zeroBasedPosition) {
|
||||
if (zeroBasedPosition >= 0) {
|
||||
Waypoint removedWaypoint;
|
||||
Util.lock(lock.writeLock());
|
||||
LockUtil.lock(lock.writeLock());
|
||||
try {
|
||||
boolean isLast = zeroBasedPosition == waypoints.size() - 1;
|
||||
removedWaypoint = waypoints.remove(zeroBasedPosition);
|
||||
@@ -354,7 +354,7 @@ public class CourseImpl extends NamedImpl implements Course {
|
||||
|
||||
@Override
|
||||
public void update(List<ControlPoint> newControlPoints, DomainFactory baseDomainFactory) throws PatchFailedException {
|
||||
Util.lock(lock.writeLock());
|
||||
LockUtil.lock(lock.writeLock());
|
||||
try {
|
||||
Iterable<Waypoint> courseWaypoints = getWaypoints();
|
||||
List<Waypoint> newWaypointList = new LinkedList<Waypoint>();
|
||||
|
||||
+9
-9
@@ -26,7 +26,6 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.confidence.ConfidenceFactory;
|
||||
import com.sap.sailing.domain.confidence.Weigher;
|
||||
@@ -40,6 +39,7 @@ import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||
import com.sap.sailing.util.SerializableComparator;
|
||||
import com.sap.sailing.util.impl.ArrayListNavigableSet;
|
||||
import com.sap.sailing.util.impl.LockUtil;
|
||||
|
||||
/**
|
||||
* A virtual wind track that computes and caches the wind bearing based on the boat tracks recorded in the tracked race
|
||||
@@ -183,7 +183,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
* Synchronizes serialization on this object to avoid the cache being updated while being written.
|
||||
*/
|
||||
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
|
||||
Util.lock(cacheLock.readLock());
|
||||
LockUtil.lock(cacheLock.readLock());
|
||||
lockForRead();
|
||||
try {
|
||||
s.defaultWriteObject();
|
||||
@@ -228,7 +228,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
// can't use lockForWrite() here because caching can happen while holding the read lock, and the lock can't be
|
||||
// upgraded. But lockForRead() and synchronization will do the job because all invalidations lock the write lock,
|
||||
// and all contains() checks and get() calls use synchronization too.
|
||||
Util.lock(cacheLock.writeLock());
|
||||
LockUtil.lock(cacheLock.writeLock());
|
||||
try {
|
||||
// synchronization necessary to protect writeObject from ConcurrentModificationException
|
||||
synchronized (this) {
|
||||
@@ -240,7 +240,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
timePointsWithCachedNullResultFastContains.add(timePoint);
|
||||
}
|
||||
} else {
|
||||
Util.lock(cacheLock.writeLock());
|
||||
LockUtil.lock(cacheLock.writeLock());
|
||||
try {
|
||||
cache.add(fix);
|
||||
} finally {
|
||||
@@ -282,7 +282,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
* running.
|
||||
*/
|
||||
private void invalidateCache() {
|
||||
Util.lock(cacheLock.writeLock());
|
||||
LockUtil.lock(cacheLock.writeLock());
|
||||
try {
|
||||
Iterator<WindWithConfidence<TimePoint>> iter = (scheduledRefreshInterval.getStart() == null ? getCachedFixes()
|
||||
: getCachedFixes().tailSet(scheduledRefreshInterval.getStart(), /* inclusive */true)).iterator();
|
||||
@@ -318,7 +318,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
private void refreshCacheIncrementally() {
|
||||
Set<WindWithConfidence<TimePoint>> windFixesToRecalculate = new HashSet<WindWithConfidence<TimePoint>>();
|
||||
Set<TimePoint> cachedNullResultsToRecalculate = new HashSet<TimePoint>();
|
||||
Util.lock(cacheLock.readLock());
|
||||
LockUtil.lock(cacheLock.readLock());
|
||||
try {
|
||||
Iterator<WindWithConfidence<TimePoint>> iter = (scheduledRefreshInterval.getStart() == null ? getCachedFixes()
|
||||
: getCachedFixes().tailSet(scheduledRefreshInterval.getStart(), /* inclusive */true)).iterator();
|
||||
@@ -363,7 +363,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
}
|
||||
}
|
||||
// apply the computed cache deltas
|
||||
Util.lock(cacheLock.writeLock());
|
||||
LockUtil.lock(cacheLock.writeLock());
|
||||
try {
|
||||
for (TimePoint nullRemoval : nullRemovals) {
|
||||
timePointsWithCachedNullResult.remove(nullRemoval);
|
||||
@@ -403,7 +403,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
Util.lock(cacheLock.writeLock());
|
||||
LockUtil.lock(cacheLock.writeLock());
|
||||
try {
|
||||
cache.clear();
|
||||
timePointsWithCachedNullResult.clear();
|
||||
@@ -423,7 +423,7 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
WindWithConfidence<TimePoint> cachedFix = null;
|
||||
WindWithConfidence<TimePoint> result = null;
|
||||
final boolean nullResultCacheContains;
|
||||
Util.lock(cacheLock.readLock());
|
||||
LockUtil.lock(cacheLock.readLock());
|
||||
try {
|
||||
nullResultCacheContains = nullResultCacheContains(timePoint);
|
||||
if (nullResultCacheContains) {
|
||||
|
||||
@@ -9,9 +9,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import com.sap.sailing.domain.base.Timed;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.tracking.Track;
|
||||
import com.sap.sailing.util.impl.ArrayListNavigableSet;
|
||||
import com.sap.sailing.util.impl.LockUtil;
|
||||
import com.sap.sailing.util.impl.UnmodifiableNavigableSet;
|
||||
|
||||
public class TrackImpl<FixType extends Timed> implements Track<FixType> {
|
||||
@@ -63,7 +63,7 @@ public class TrackImpl<FixType extends Timed> implements Track<FixType> {
|
||||
|
||||
@Override
|
||||
public void lockForRead() {
|
||||
Util.lock(readWriteLock.readLock());
|
||||
LockUtil.lock(readWriteLock.readLock());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,7 +72,7 @@ public class TrackImpl<FixType extends Timed> implements Track<FixType> {
|
||||
}
|
||||
|
||||
protected void lockForWrite() {
|
||||
Util.lock(readWriteLock.writeLock());
|
||||
LockUtil.lock(readWriteLock.writeLock());
|
||||
}
|
||||
|
||||
protected void unlockAfterWrite() {
|
||||
|
||||
+2
-1
@@ -82,6 +82,7 @@ import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||
import com.sap.sailing.util.impl.LockUtil;
|
||||
import com.sap.sailing.util.impl.SmartFutureCache;
|
||||
import com.sap.sailing.util.impl.SmartFutureCache.AbstractCacheUpdater;
|
||||
import com.sap.sailing.util.impl.SmartFutureCache.EmptyUpdateInterval;
|
||||
@@ -755,7 +756,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
||||
lock = readWriteLock.readLock();
|
||||
}
|
||||
}
|
||||
Util.lock(lock);
|
||||
LockUtil.lock(lock);
|
||||
try {
|
||||
if (rankedCompetitors == null) {
|
||||
rankedCompetitors = competitorRankings.get(timePoint); // try again; maybe a writer released the write lock after updating the cache
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.sap.sailing.util.impl;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
|
||||
public class LockUtil {
|
||||
private static final int NUMBER_OF_SECONDS_TO_WAIT_FOR_LOCK = 5;
|
||||
private static final Logger logger = Logger.getLogger(Util.class.getName());
|
||||
|
||||
/**
|
||||
* Bug <a href="http://bugs.sun.com/view_bug.do?bug_id=6822370">http://bugs.sun.com/view_bug.do?bug_id=6822370</a> seems
|
||||
* dangerous, particularly if it happens in a <code>LiveLeaderboardUpdater</code> thread. Even though the bug is reported to
|
||||
* have been fixed in JDK 7(b79) we should be careful. This method tries to acquire a lock, allowing for five seconds to pass.
|
||||
* After five seconds and not having retrieved the lock, tries again until the lock has been acquired.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public static void lock(Lock lock) {
|
||||
boolean locked = false;
|
||||
boolean interrupted = false;
|
||||
while (!locked) {
|
||||
try {
|
||||
locked = lock.tryLock(NUMBER_OF_SECONDS_TO_WAIT_FOR_LOCK, TimeUnit.SECONDS);
|
||||
if (!locked) {
|
||||
logger.info("Couldn't acquire lock in "+NUMBER_OF_SECONDS_TO_WAIT_FOR_LOCK+"s. Trying again...");
|
||||
}
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
interrupted = true;
|
||||
}
|
||||
}
|
||||
if (interrupted) {
|
||||
// re-assert interrupt state that occurred while we
|
||||
// were acquiring the lock
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.util.impl.SmartFutureCache.UpdateInterval;
|
||||
|
||||
/**
|
||||
@@ -193,7 +192,7 @@ public class SmartFutureCache<K, V, U extends UpdateInterval<U>> {
|
||||
public V call() {
|
||||
try {
|
||||
V preResult = cacheUpdateComputer.computeCacheUpdate(key, joinedUpdateInterval);
|
||||
Util.lock(getOrCreateLockForKey(key).writeLock());
|
||||
LockUtil.lock(getOrCreateLockForKey(key).writeLock());
|
||||
try {
|
||||
V result = cacheUpdateComputer.provideNewCacheValue(key, cache.get(key), preResult, joinedUpdateInterval);
|
||||
if (result == null) {
|
||||
@@ -239,7 +238,7 @@ public class SmartFutureCache<K, V, U extends UpdateInterval<U>> {
|
||||
}
|
||||
} // else no calculation currently going on; value has been fetched from latest cache entry
|
||||
} else {
|
||||
Util.lock(getOrCreateLockForKey(key).readLock());
|
||||
LockUtil.lock(getOrCreateLockForKey(key).readLock());
|
||||
try {
|
||||
value = cache.get(key);
|
||||
} finally {
|
||||
|
||||
Reference in new issue
Block a user