[英]Reentrant readwrite lock synchronization on isWriteLocked
我目前正在考虑实现一个会话管理器 java 类,该类提供按需读取和刷新会话令牌的功能。 如果正在刷新会话令牌(即从服务器获取),则会话令牌读取器应阻塞,直到刷新完成。 类似地,在任何正在进行的读取未完成之前,都会阻止刷新请求。 由于会话令牌读取请求与会话令牌刷新请求相比非常频繁,因此我决定使用 ReentrantReadWriteLock 来实现读取和刷新之间的同步。 这是它的外观:
String refreshToken() {
try{
if (readWriteLock.writeLock().trylock()) {
//fetch session from server and store on disk
}
} finally {
readWriteLock.writeLock().unlock();
}
return readToken();
}
String readToken() {
try {
readWriteLock.readLock().lock();
//read token from disk
} finally {
readWriteLock.readLock().unlock();
}
return token;
}
}
我的第一次尝试是在写锁上使用 tryLock() 以便如果它已经被锁定写入,则 tryLock() 将返回 false 然后获取读锁并阻塞直到写锁被释放从而重新调度读阻塞线程完成读取。 该逻辑适用于多个线程同时调用 refreshSession() 从而仅允许一个线程启动会话令牌刷新而所有其他线程失败并阻塞读取锁的情况。
然而,如果一个线程刚刚获得了一个读锁(通过调用 readToken())并且另一个线程调用 refreshToken() 来获得一个写锁,那么上面的逻辑就会失败——在这种情况下,tryLock() 将失败,因为它缺少刷新请求结果。
作为替代方案,我查看了 readWriteLock.isWriteLocked() 方法,该方法检查是否有任何线程获得了写锁:
String refreshToken() {
try{
if (!readWriteLock.isWriteLocked()) {
readWriteLock.writeLock().lock();
//fetch session from server and store on disk
} finally{
readWriteLock.writeLock().unlock();
}
}
return readToken();
}
但是,我对这种方法没有太多经验,并且不完全确定它会产生的同步影响,因为我想确保只有一个线程可以获取写锁,并且后续请求会落入读取。 任何建议/指针将不胜感激。
你可以在那里引入一个新的ReentrantLock
和tryLock
。 ReentrantLock 只承诺一个写入者,如果存在写入者,则很快就会失败。
ReentrantLock lock = new ReentrantLock();
public String refreshToken() {
if (lock.tryLock()) {
readWriteLock.writeLock().lock();
try {
// fetch session from server and store on disk
} finally {
readWriteLock.writeLock().unlock();
}
}
return readToken();
}
所以只有一个线程会尝试写入。 并且在写入过程中没有线程可以读取。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.