Wiki Markup |
---|
An exceptional condition can circumvent the release of a lock, leading to deadlock. According to the Java API \[[API 2006|AA. Bibliography#API 06]\]: |
A
ReentrantLock
is owned by the thread last successfully locking, but not yet unlocking it. A thread invokinglock
will return, successfully acquiring the lock, when the lock is not owned by another thread.
...
This compliant solution encapsulates operations that may could throw an exception in a try
block immediately after acquiring the lock. The lock is acquired just before the try block, which guarantees that it is held when the finally
block executes. Invoking Lock.unlock()
in the finally
block ensures that the lock is released, regardless of whether or not an exception occurs.
Code Block | ||
---|---|---|
| ||
public final class Client { public void doSomething(File file) { final Lock lock = new ReentrantLock(); InputStream in = null; lock.lock(); try { in = new FileInputStream(file); // Perform operations on the open file } catch (FileNotFoundException fnf) { // Forward to handler } finally { lock.unlock(); if (in != null) { try { in.close(); } catch (IOException e) { // Forward to handler } } } } } |
Compliant Solution (Execute-
...
Around Idiom)
The execute-around idiom provides a generic mechanism to perform resource allocation and clean-up operations so that the client can focus on specifying only the required functionality. This idiom reduces clutter in client code and provides a secure mechanism for resource management.
...
Failing to release locks on exceptional conditions may could lead to thread starvation and deadlock.
...