我正在使用 StampedLock
实现缓存读取或加载方法,我想知道我是否可以更好地调整javadoc中的示例。
作者Doug Lea给出了一个'乐观读'示例和一个'升级读锁定写锁'的例子,但在我的用例中我想要同时做两件事。
public String getConverted(String input) {
String customised = null;
long stamp = 0L;
while (customised == null) {
if (!lock.validate(stamp)) {
stamp = lock.tryOptimisticRead();
}
customised = cached.get(input);
// if the lock was valid we can trust the value of customised
if (lock.validate(stamp) && customised == null) {
long writeStamp = 0L;
try {
while (customised == null) {
writeStamp = lock.tryConvertToWriteLock(stamp);
if (writeStamp != 0L) {
stamp = writeStamp;
customised = convertToCustom(input);
cached.put(input, customised);
} else {
// so what do we do here (line 15)?
}
}
} finally {
lock.unlock(stamp);
}
} else {
// if the lock was invalid, customised could be anything, so:
customised = null;
// and what do we do here (line 25)?
}
}
return customised;
}
因此算法中有两点需要做点什么 - 在两种情况下都是:
获取硬锁 - 在第15行:
lock.unlockRead(stamp);
stamp = lock.writeLock();
并在第25行:
stamp = lock.readLock();
或者是什么?
Thread.sleep(25);
这对我来说并没有削减它 - 当然StampedLock
可以更好地管理这个线程上的阻塞!
readLock()
或writeLock()
,那么我会在StampedLock#tryOptimisticRead()
和StampedLock#tryConvertToWriteLock()
内放弃经过良好编码和测试的排队算法。
或者这些方法背后的逻辑是否因为失败一次而被没收?
答案 0 :(得分:2)
您可以查看以下方法以供参考。
tryConvertToWriteLock和tryOptimisticRead中没有排队机制。
方法tryOptimisticRead()仅在锁定时返回非零标记 目前未处于写入模式。方法验证(long)返回 如果在获取a之后未在写入模式下获取锁定,则为true 给予邮票。这种模式可以被认为是一个非常弱的版本 读锁定,可以随时由作者打破。指某东西的用途 短只读代码段的乐观模式通常会减少 争用并提高吞吐量。但是,它的使用本质上是有用的 脆弱。乐观的阅读部分应该只读取字段并保持 它们在局部变量中供以后验证后使用。字段读取 而在乐观模式下可能会非常不一致,因此适用 只有当您熟悉数据表示才能检查时 一致性和/或反复调用方法validate()。例如, 首次阅读对象时通常需要执行此类步骤 数组引用,然后访问其中一个字段,元素或 方法
另外,我喜欢你检查乐观锁定有效性的控制流程,如果你发现它是无效的,那么就获得锁定,因为它避免了" else"代码中使用的块。
tryConvertToWriteLock 的类似代码流。
private final StampedLock sl = new StampedLock();
/**
* This method is to show the feature of tryOptimisticRead() method
*/
public double getTotalRevenueOptimisticRead() {
long stamp = sl.tryOptimisticRead();
double balance = this.totalRevenue;
boolean lockAcquired = false;
//calling validate(stamp) method to ensure that stamp is valid, if not then acquiring the read lock
if (!sl.validate(stamp)){
lockAcquired = true;
LOG.info("stamp for tryOptimisticRead() is not valid now, so acquiring the read lock");
stamp = sl.readLock();
}
try {
balance = this.totalRevenue;
} finally {
if(lockAcquired){
sl.unlockRead(stamp);
}
}
return balance;
}
/**
* This method is to show the feature of tryConvertToWriteLock() method
*/
public double getStateTaxReturnUisngConvertToWriteLock(TaxPayer taxPayer) {
double incomeTaxRetunAmount = taxPayer.getTaxAmount() * 5/100;
long stamp = sl.readLock();
boolean lockAcquired = false;
//Trying to upgrade the lock from read to write
stamp = sl.tryConvertToWriteLock(stamp);
//Checking if tryConvertToWriteLock got success otherwise call writeLock method
if(stamp == 0L){
LOG.info("stamp is zero for tryConvertToWriteLock(), so acquiring the write lock");
stamp = sl.writeLock();
lockAcquired = true;
}
try {
this.totalRevenue -= incomeTaxRetunAmount;
} finally {
if(lockAcquired){
sl.unlockWrite(stamp);
}
}
return incomeTaxRetunAmount;
}