/*
* Copyright (c) 2013-2017 Cinchapi Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cinchapi.concourse.server.concurrent;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import java.util.concurrent.locks.StampedLock;
/**
* Lock related utility methods.
*
* @author Jeff Nelson
*/
public final class Locks {
/**
* Call {@link Lock#lock()} if and only if {@code condition} is {@code true}
*
* @param lock
* @param condition
*/
public static void lockIfCondition(Lock lock, boolean condition) {
if(condition) {
lock.lock();
}
}
/**
* Return a {@link ReadLock} that is non-operational and always returns
* immediately without actually acquiring any shared or exclusive holds on
* any monitor.
*
* @return the noop ReadLock
*/
public static ReadLock noOpReadLock() {
return NOOP_READ_LOCK;
}
/**
* Return a {@link StampedLock} that is non-operational and always returns
* immediately without actually acquiring and shard or exclusive holds on
* any monitor.
*
* @return the noop StampedLock
*/
public static StampedLock noOpStampedLock() {
return NOOP_STAMPED_LOCK;
}
/**
* Return a {@link WriteLock} that is non-operational and always returns
* immediately without actually acquiring any shared or exclusive holds on
* any monitor.
*
* @return the noop WriteLock
*/
public static WriteLock noOpWriteLock() {
return NOOP_WRITE_LOCK;
}
/**
* Decorator to call {@link StampedLock#readLock()} if the {@code condition}
* is {@code true}.
*
* @param lock
* @param condition
* @return the stamp
*/
public static long stampLockReadIfCondition(StampedLock lock,
boolean condition) {
return condition ? lock.readLock() : 0L;
}
/**
* Decorator to call {@link StampedLock#writeLock()} if the
* {@code condition} is {@code true}.
*
* @param lock
* @param condition
* @return the stamp
*/
public static long stampLockWriteIfCondition(StampedLock lock,
boolean condition) {
return condition ? lock.writeLock() : 0L;
}
/**
* Decorator to call {@link StampedLock#unlockRead(long)} if the
* {@code condition} is {@code true}.
*
* @param lock
* @param condition
*/
public static void stampUnlockReadIfCondition(StampedLock lock, long stamp,
boolean condition) {
if(condition) {
lock.unlockRead(stamp);
}
}
/**
* Decorator to call {@link StampedLock#unlockWrite(long)} if the
* {@code condition} is {@code true}.
*
* @param lock
* @param condition
*/
public static void stampUnlockWriteIfCondition(StampedLock lock,
long stamp, boolean condition) {
if(condition) {
lock.unlockWrite(stamp);
}
}
/**
* Call {@link Lock#unlock()} if and only if {@code condition} is
* {@code true}. This method DOES NOT check to see if the lock is actually
* held.
*
* @param lock
* @param condition
*/
public static void unlockIfCondition(Lock lock, boolean condition) {
if(condition) {
lock.unlock();
}
}
/**
* The lock that is returned by the {@link #noOpReadLock()} method.
*/
@SuppressWarnings("serial")
private static final ReadLock NOOP_READ_LOCK = new ReadLock(
new ReentrantReadWriteLock()) {
@Override
public void lock() {}
@Override
public boolean tryLock() {
return true;
}
@Override
public void unlock() {}
};
/**
* A {@link StampedLock} that does not do anything. This is returned by the
* {@link #noOpStampedLock()} method.
*/
@SuppressWarnings("serial")
private static final StampedLock NOOP_STAMPED_LOCK = new StampedLock() {
@Override
public long readLock() {
return 0;
}
@Override
public long tryOptimisticRead() {
return 0;
}
@Override
public void unlock(long stamp) {/* noop */}
@Override
public boolean validate(long stamp) {
return true;
}
@Override
public long writeLock() {
return 0;
}
};
/**
* The lock that is returned by the {@link #noOpWriteLock()} method.
*/
@SuppressWarnings("serial")
private static final WriteLock NOOP_WRITE_LOCK = new WriteLock(
new ReentrantReadWriteLock()) {
@Override
public void lock() {}
@Override
public boolean tryLock() {
return true;
}
@Override
public void unlock() {}
};
}