StampedLock # tryOptimisticRead () реализация - PullRequest
0 голосов
/ 03 мая 2018

Я реализую метод чтения или загрузки из кэша с помощью StampedLock, и мне интересно, могу ли я адаптировать примеры из javadoc лучше, чем этот.

Автор Дуг Ли дал пример «оптимистического чтения» и пример «обновить блокировку чтения до блокировки записи», но в моем случае я хочу сделать оба вместе.

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(stamp);
                        stamp = lock.writeLock();
    

    и в строке 25:

                        stamp = lock.readLock();
    
  2. Или что?

                        Thread.sleep(25); 
    

, который мне не подходит - конечно, StampedLock может лучше справляться с блокировками в этом потоке!

Но как? Если я просто позвоню readLock() или writeLock(), то я откажусь от хорошо закодированных и проверенных алгоритмов организации очередей внутри StampedLock#tryOptimisticRead() и StampedLock#tryConvertToWriteLock().

Или логика, лежащая в основе этих методов, уже утрачена, потому что они однажды потерпели неудачу?

1 Ответ

0 голосов
/ 03 мая 2018

Вы можете взглянуть на следующие методы для справки.

В tryConvertToWriteLock и tryOptimisticRead отсутствует механизм организации очереди.

Метод tryOptimisticRead () возвращает ненулевой штамп, только если блокировка в настоящее время не находится в режиме записи. Метод validate (long) возвращает истина, если блокировка не была получена в режиме записи с момента получения данный штамп. Этот режим можно считать крайне слабой версией блокировки чтения, которая может быть взломана автором в любое время. Использование оптимистичный режим для коротких сегментов кода только для чтения часто уменьшает Разногласия и улучшает пропускную способность. Тем не менее, его использование по своей сути хрупкий. Оптимистичные разделы чтения должны только читать поля и держать их в локальных переменных для последующего использования после проверки. Поля читать в то время как в оптимистическом режиме может быть крайне противоречивым, поэтому использование применяется только когда вы достаточно знакомы с представлениями данных, чтобы проверить согласованность и / или многократный вызов метода 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; 
  }  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...