2016-03-15 2 views
3

ниже код был помечен как нарушения Fortify («неизданный ресурсов» для замка)tryLock неизданные ресурс

try { 
    if (lock.tryLock(1, TimeUnit.SECONDS)) { 
    try { 
     //do something 
    } 
    finally { 
     lock.unlock(); 
    } 
} 
catch (InterruptedException e) { 
    // something 
} 

Не могли бы вы объяснить, почему? Должно ли быть выражение finally для InterruptedException try/catch? Я думал, что внутренняя попытка будет справляться и с этим делом.

+1

это прекрасно выглядит ... – assylias

+1

Это просто интерфейс 'Lock'? –

+2

Я думаю, что это ошибка Fortify - код выглядит хорошо. –

ответ

4

Fortify документация описывает unreleased resource bug как:

Программа потенциально может не выпустить системный ресурс.

Это не относится к вашему примеру. Если tryLock возвращает false или генерирует исключение, блокировка не была получена, блок try не вводится, и нет ничего, что можно было бы отменить (поэтому в внешнем блоке try не требуется окончательный блок). Если tryLock возвращает true, внутренний блок try вводится и блокировка освобождается в конце.

То, что вы, кажется, идентичен тому, как API documentation рекомендует вам сделать это:

Lock lock = ...; 
    if (lock.tryLock()) { 
     try { 
      // manipulate protected state 
     } finally { 
      lock.unlock(); 
     } 
    } else { 
     // perform alternative actions 
    } 

Единственным отличием является ваш пример использует переопределение tryLock, что тайм-аут, в этом случае она возвращает ложь. Поэтому из того, что опубликовано, кажется, все в порядке.

+0

Есть еще одно ключевое отличие: локальная переменная 'lock'. Если OP ссылается на член класса, возможно, что ссылка будет заменена во время блокировки. – shmosel

+0

@shmosel: Это интересный момент. Но если замок будет заменен, кажется, что проблемы хуже. –

+0

Я не утверждаю, что это так, что Fortify не может быть уверен. – shmosel

Смежные вопросы