首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >StampedLock#tryOptimisticRead()实现

StampedLock#tryOptimisticRead()实现
EN

Stack Overflow用户
提问于 2018-05-03 15:32:46
回答 1查看 625关注 0票数 0

我正在用StampedLock实现缓存读取或加载方法,我想知道我是否能够更好地修改来自javadoc的示例。

作者Doug给出了一个“乐观阅读”示例和一个“升级读锁写锁”示例,但在我的用例中,我想两者结合使用。

代码语言:javascript
复制
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;
}

因此,在算法中有两点我需要做一些事情--在这两种情况下都是这样:

  1. 获得硬锁-在第15行: Lock.unlockRead(邮票);邮票= lock.writeLock(); 在第25行: 邮票= lock.readLock();
  2. 不然呢? Thread.sleep(25);

这并不能帮我解决这个问题--当然,StampedLock可以更好地管理这个线程的阻塞!

但是怎么做呢?如果我只调用readLock()writeLock(),那么我就放弃了在StampedLock#tryOptimisticRead()StampedLock#tryConvertToWriteLock()中经过良好编码和测试的排队算法。

还是那些方法背后的逻辑已经丧失,因为它们曾经失败过一次?

EN

回答 1

Stack Overflow用户

发布于 2018-05-03 16:40:25

您可以查看以下方法以供参考。

在tryConvertToWriteLock和tryOptimisticRead.中没有排队机制

方法tryOptimisticRead()仅在锁当前未处于写模式时才返回非零邮票。如果锁自获得给定的戳记后还没有在写入模式下获得,则方法write (Long)返回true。这种模式可以被认为是读锁的一个非常弱的版本,在任何时候都可以被作者打破。对短只读代码段使用乐观模式通常可以减少争用并提高吞吐量。然而,它的使用本质上是脆弱的。乐观读取部分只应读取字段并将其保存在局部变量中,供验证后使用。在乐观模式下读取的字段可能非常不一致,因此只有当您熟悉数据表示以检查一致性和/或反复调用方法usage ()时,才能应用。例如,当首先读取对象或数组引用,然后访问其字段、元素或方法之一时,通常需要这样的步骤。

另外,我喜欢检查乐观锁的有效性的控制流,如果发现它无效,那么获取锁,因为它避免了代码中使用的“否则”块的需要。

tryConvertToWriteLock.的相似代码流

代码语言:javascript
复制
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; 
  }  
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50158850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档