Use ReentrantLock instead of intrinsic locks in LockBasedStorageManager

This commit is contained in:
Andrey Breslav
2013-10-02 14:53:35 +04:00
parent ee72479344
commit 0c83832f27
2 changed files with 74 additions and 28 deletions
@@ -29,6 +29,7 @@ import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice; import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.locks.Lock;
public class LockBasedLazyResolveStorageManager extends LockBasedStorageManager implements LazyResolveStorageManager { public class LockBasedLazyResolveStorageManager extends LockBasedStorageManager implements LazyResolveStorageManager {
@NotNull @NotNull
@@ -40,10 +41,10 @@ public class LockBasedLazyResolveStorageManager extends LockBasedStorageManager
} }
private static class LockProtectedContext implements BindingContext { private static class LockProtectedContext implements BindingContext {
private final Object lock; private final Lock lock;
private final BindingContext context; private final BindingContext context;
private LockProtectedContext(Object lock, BindingContext context) { private LockProtectedContext(Lock lock, BindingContext context) {
this.lock = lock; this.lock = lock;
this.context = context; this.context = context;
} }
@@ -51,43 +52,59 @@ public class LockBasedLazyResolveStorageManager extends LockBasedStorageManager
@NotNull @NotNull
@Override @Override
public Diagnostics getDiagnostics() { public Diagnostics getDiagnostics() {
synchronized (lock) { lock.lock();
try {
return context.getDiagnostics(); return context.getDiagnostics();
} }
finally {
lock.unlock();
}
} }
@Nullable @Nullable
@Override @Override
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) { public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
synchronized (lock) { lock.lock();
try {
return context.get(slice, key); return context.get(slice, key);
} }
finally {
lock.unlock();
}
} }
@NotNull @NotNull
@Override @Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) { public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
synchronized (lock) { lock.lock();
try {
return context.getKeys(slice); return context.getKeys(slice);
} }
finally {
lock.unlock();
}
} }
@NotNull @NotNull
@Override @Override
@TestOnly @TestOnly
public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) { public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) {
synchronized (lock) { lock.lock();
try {
return context.getSliceContents(slice); return context.getSliceContents(slice);
} }
finally {
lock.unlock();
}
} }
} }
private static class LockProtectedTrace implements BindingTrace { private static class LockProtectedTrace implements BindingTrace {
private final Object lock; private final Lock lock;
private final BindingTrace trace; private final BindingTrace trace;
private final BindingContext context; private final BindingContext context;
public LockProtectedTrace(@NotNull Object lock, @NotNull BindingTrace trace) { public LockProtectedTrace(@NotNull Lock lock, @NotNull BindingTrace trace) {
this.lock = lock; this.lock = lock;
this.trace = trace; this.trace = trace;
this.context = new LockProtectedContext(lock, trace.getBindingContext()); this.context = new LockProtectedContext(lock, trace.getBindingContext());
@@ -100,39 +117,59 @@ public class LockBasedLazyResolveStorageManager extends LockBasedStorageManager
@Override @Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) { public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
synchronized (lock) { lock.lock();
try {
trace.record(slice, key, value); trace.record(slice, key, value);
} }
finally {
lock.unlock();
}
} }
@Override @Override
public <K> void record(WritableSlice<K, Boolean> slice, K key) { public <K> void record(WritableSlice<K, Boolean> slice, K key) {
synchronized (lock) { lock.lock();
try {
trace.record(slice, key); trace.record(slice, key);
} }
finally {
lock.unlock();
}
} }
@Override @Override
@Nullable @Nullable
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) { public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
synchronized (lock) { lock.lock();
try {
return trace.get(slice, key); return trace.get(slice, key);
} }
finally {
lock.unlock();
}
} }
@Override @Override
@NotNull @NotNull
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) { public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
synchronized (lock) { lock.lock();
try {
return trace.getKeys(slice); return trace.getKeys(slice);
} }
finally {
lock.unlock();
}
} }
@Override @Override
public void report(@NotNull Diagnostic diagnostic) { public void report(@NotNull Diagnostic diagnostic) {
synchronized (lock) { lock.lock();
try {
trace.report(diagnostic); trace.report(diagnostic);
} }
finally {
lock.unlock();
}
} }
} }
} }
@@ -27,15 +27,12 @@ import org.jetbrains.jet.utils.WrappedValues;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockBasedStorageManager implements StorageManager { public class LockBasedStorageManager implements StorageManager {
protected final Object lock = new Object() { protected final Lock lock = new ReentrantLock();
@Override
public String toString() {
return "LockBasedStorageManager centralized lock";
}
};
@NotNull @NotNull
@Override @Override
@@ -134,9 +131,13 @@ public class LockBasedStorageManager implements StorageManager {
@Override @Override
public <T> T compute(@NotNull Computable<T> computable) { public <T> T compute(@NotNull Computable<T> computable) {
synchronized (lock) { lock.lock();
try {
return computable.compute(); return computable.compute();
} }
finally {
lock.unlock();
}
} }
private static class LockBasedLazyValue<T> implements NullableLazyValue<T> { private static class LockBasedLazyValue<T> implements NullableLazyValue<T> {
@@ -144,13 +145,13 @@ public class LockBasedStorageManager implements StorageManager {
private static final Object NOT_COMPUTED = new Object(); private static final Object NOT_COMPUTED = new Object();
private static final Object COMPUTING = new Object(); private static final Object COMPUTING = new Object();
private final Object lock; private final Lock lock;
private final Computable<T> computable; private final Computable<T> computable;
@Nullable @Nullable
private volatile Object value = NOT_COMPUTED; private volatile Object value = NOT_COMPUTED;
public LockBasedLazyValue(@NotNull Object lock, @NotNull Computable<T> computable) { public LockBasedLazyValue(@NotNull Lock lock, @NotNull Computable<T> computable) {
this.lock = lock; this.lock = lock;
this.computable = computable; this.computable = computable;
} }
@@ -165,7 +166,8 @@ public class LockBasedStorageManager implements StorageManager {
Object _value = value; Object _value = value;
if (_value != NOT_COMPUTED && _value != COMPUTING) return WrappedValues.unescapeThrowable(_value); if (_value != NOT_COMPUTED && _value != COMPUTING) return WrappedValues.unescapeThrowable(_value);
synchronized (lock) { lock.lock();
try {
_value = value; _value = value;
if (_value == COMPUTING) { if (_value == COMPUTING) {
Object result = recursionDetected(); Object result = recursionDetected();
@@ -188,6 +190,9 @@ public class LockBasedStorageManager implements StorageManager {
throw ExceptionUtils.rethrow(throwable); throw ExceptionUtils.rethrow(throwable);
} }
} }
finally {
lock.unlock();
}
} }
/** /**
@@ -206,7 +211,7 @@ public class LockBasedStorageManager implements StorageManager {
private static class LockBasedNotNullLazyValue<T> extends LockBasedLazyValue<T> implements NotNullLazyValue<T> { private static class LockBasedNotNullLazyValue<T> extends LockBasedLazyValue<T> implements NotNullLazyValue<T> {
public LockBasedNotNullLazyValue(@NotNull Object lock, @NotNull Computable<T> computable) { public LockBasedNotNullLazyValue(@NotNull Lock lock, @NotNull Computable<T> computable) {
super(lock, computable); super(lock, computable);
} }
@@ -220,11 +225,11 @@ public class LockBasedStorageManager implements StorageManager {
} }
private static class MapBasedMemoizedFunction<K, V> implements MemoizedFunctionToNullable<K, V> { private static class MapBasedMemoizedFunction<K, V> implements MemoizedFunctionToNullable<K, V> {
private final Object lock; private final Lock lock;
private final ConcurrentMap<K, Object> cache; private final ConcurrentMap<K, Object> cache;
private final Function<K, V> compute; private final Function<K, V> compute;
public MapBasedMemoizedFunction(@NotNull Object lock, @NotNull ConcurrentMap<K, Object> map, @NotNull Function<K, V> compute) { public MapBasedMemoizedFunction(@NotNull Lock lock, @NotNull ConcurrentMap<K, Object> map, @NotNull Function<K, V> compute) {
this.lock = lock; this.lock = lock;
this.cache = map; this.cache = map;
this.compute = compute; this.compute = compute;
@@ -236,7 +241,8 @@ public class LockBasedStorageManager implements StorageManager {
Object value = cache.get(input); Object value = cache.get(input);
if (value != null) return WrappedValues.unescapeExceptionOrNull(value); if (value != null) return WrappedValues.unescapeExceptionOrNull(value);
synchronized (lock) { lock.lock();
try {
value = cache.get(input); value = cache.get(input);
if (value != null) return WrappedValues.unescapeExceptionOrNull(value); if (value != null) return WrappedValues.unescapeExceptionOrNull(value);
@@ -254,13 +260,16 @@ public class LockBasedStorageManager implements StorageManager {
throw ExceptionUtils.rethrow(throwable); throw ExceptionUtils.rethrow(throwable);
} }
} }
finally {
lock.unlock();
}
} }
} }
private static class MapBasedMemoizedFunctionToNotNull<K, V> extends MapBasedMemoizedFunction<K, V> implements MemoizedFunctionToNotNull<K, V> { private static class MapBasedMemoizedFunctionToNotNull<K, V> extends MapBasedMemoizedFunction<K, V> implements MemoizedFunctionToNotNull<K, V> {
public MapBasedMemoizedFunctionToNotNull( public MapBasedMemoizedFunctionToNotNull(
@NotNull Object lock, @NotNull Lock lock,
@NotNull ConcurrentMap<K, Object> map, @NotNull ConcurrentMap<K, Object> map,
@NotNull Function<K, V> compute @NotNull Function<K, V> compute
) { ) {