...
This noncompliant code example does not close the input stream and, consequently, also violates guideline FIO06-J. Ensure all resources are properly closed when they are no longer needed.
Compliant Solution (finally
...
Block)
This compliant solution encapsulates operations that may 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 interface LockAction { void doSomethingWithFile(InputStream in); } public final class ReentrantLockAction { public static void doSomething(File file, LockAction action) { Lock lock = new ReentrantLock(); InputStream in = null; lock.lock(); try { in = new FileInputStream(file); action.doSomethingWithFile(in); } catch (FileNotFoundException fnf) { // Forward to handler } finally { lock.unlock(); if (in != null) { try { in.close(); } catch (IOException e) { // Forward to handler } } } } } public final class Client { public void doSomething(File file) { ReentrantLockAction.doSomething(file, new LockAction() { public void doSomethingWithFile(InputStream in) { // Perform operations on the open file } }); } } |
Noncompliant Code Example (
...
Unchecked Exception)
This noncompliant code example uses a ReentrantLock
to protect a java.util.Date
instance, which is not thread-safe by design. The doSomethingSafely()
method must catch Throwable
to comply with guideline EXC06-J. Do not allow exceptions to transmit sensitive information.
...
Because the doSomething()
method fails to check if str
is null, a runtime exception can occur, preventing the lock from being released.
Compliant Solution (finally
...
Block)
This compliant solution encapsulates all operations that can throw an exception in a try
block and release releases the lock in the associated finally
block.
...