The shared resource can be controlled by a lock. Before a thread can access a shared resource, it has to get the lock that protects that resource. When access to the resource is complete, the lock is released.
If a second thread acquires the lock when the lock is in use, the second thread is suspended until the lock is released.
To acquire a lock, call lock( ). If the lock is unavailable, lock( ) will wait.
To release a lock, call unlock( ).
To see if a lock is available, and to acquire it if it is, call tryLock( ). It returns true if the lock is acquired and false otherwise.
The newCondition( ) method returns a Condition object associated with the lock. With Condition object, you can control the lock through methods such as await( ) and signal( ). await( ) and signal( ) are similar to Object.wait( ) and Object.notify( ).
java.util.concurrent.locks supplies an implementation of Lock called ReentrantLock. ReentrantLock implements a reentrant lock, which is a lock that can be repeatedly entered by the thread that currently holds the lock. Otherwise, a thread seeking to acquire the lock will suspend until the lock is not in use