Unreleased Lock

ID

java.unreleased_lock

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

CWE:764, concurrency, reliability

Description

Reports calls to Lock.lock() or Lock.lockInterruptibly() that are not protected by a try/finally block containing the corresponding unlock() call. If an exception is thrown between lock() and unlock(), the lock is never released, permanently blocking all other threads that attempt to acquire it.

Rationale

Unlike synchronized blocks (where the monitor is released automatically on any exit path), explicit Lock instances require the programmer to guarantee release. A missing finally block means any exception between lock acquisition and release leaves the lock permanently held.

// Bad -- if doWork() throws, lock is never released
lock.lock();
doWork();
lock.unlock();

Remediation

Always place unlock() in a finally block immediately after lock():

// Good
lock.lock();
try {
    doWork();
} finally {
    lock.unlock();
}