final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}else if (current == getExclusiveOwnerThread()) {
//如果是当前持有锁的线程再次获取锁,则将同步值进行增加并返回true
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
公平锁保证了锁的获取按照FIFO原则,而代价是进行大量的线程切换;
非公平锁虽然可能造成线程“饥饿”(即某线程可能需要等很久才得到锁),但线程切换极少,可以保证更大的吞吐量。
int getReadLockCount()
返回当前读锁被获取的次数
注意:该次数并不等于获取读锁的线程数,
因为同一线程可以连续获得多次读锁,获取一次,返回值就加1,
比如,仅一个线程,它连续获得了n次读锁,那么占据读锁的线程数是1,但该方法返回n
int getReadHoldCount()
返回当前线程获取读锁的次数
boolean isWriteLock()
判断读锁是否被获取
int getWriteHoldCount()
返回当前写锁被获取的次数
public class Cache{
//非线程安全的HashMap
private static Map<String, Object> map = new HashMap<>();
//读写锁
private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//读锁
private static Lock readLock = reentrantReadWriteLock.readLock();
//写锁
private static Lock writeLock = reentrantReadWriteLock.writeLock();
/**
* 获取key对应的value
*
* 使用读锁,使得并发访问该方法时不会被阻塞
*/
public static final Object get(String key){
readLock.lock();
try{
return map.get(key);
}finally {
readLock.unlock();
}
}
/**
* 设置key对应的value
*
* 当有线程对map进行put操作时,使用写锁,阻塞其他线程的读、写操作,
* 只有在写锁被释放后,其他读写操作才能继续
*/
public static Object put(String key, Object value){
writeLock.lock();
try {
return map.put(key, value);
}finally {
writeLock.unlock();
}
}
/**
* 清空map
*
* 当有线程对map进行清空操作时,使用写锁,阻塞其他线程的读、写操作,
* 只有在写锁被释放后,其他读写操作才能继续
*/
public static void clear(){
writeLock.lock();
try {
map.clear();
}finally {
writeLock.unlock();
}
}
}