Java — Threading Basics — Locks

Ben Parker
2 min readJan 9, 2021

--

In a single threaded application, locks are not something that you need to give any thought to. However, in multi-threaded environments, locks are an important concept to understand.

Locks are a way of ensuring that a piece of code is only executed by only thread at a time. This is an important tool, as in some situations having 2 or more threads accessing and executing the same piece of code can lead to errors and data integrity issues.

Synchronized Method & Block

If a method is decorated with the synchronized keyword, then it will be completely thread-safe. It achieves this by gaining the intrinsic lock of the object. That means that only one thread can enter that method at one time.

Example
If we have an object Foo. This object has 2 methods
foo()
bar()

Both methods are marked as synchronized.

If we have 2 threads. Thread 1 calls foo(). Since this method is synchronized, Thread 1 has to gain the intrinsic object lock for the Foo object. That means that no other thread can call any synchronized methods while Thread 1 has that lock.

Once Thread 1 has that lock, it can execute that synchronized method. Once the method is complete, the lock is released.

Although synchronized methods work well, there may be some code in that method that you do not need to synchronise. Therefore by synchronising the entire method, you are losing efficiency.

In that case, we can use the synchronized block combined with a lock object.

synchronized ( lock ) {
// Your code
}

This allows you to put only the critical logic which needs to be synchronised in the block, increasing efficiency. You are gaining the intrinsic lock of the object specified, rather than the lock of the parent object itself. This means you can create multiple lock objects, and lock different pieces of code with different locks.
You would do this if the pieces of code do not depend on each other, and so you can allow each method to be run in parallel without causing any visibility issues.

Re-entrant Lock

In some scenarios, the synchronised block does not work well. Such as when you want to lock a piece of code in one method, and unlock it in another method. In this scenario, there are available classes in Java which allow you to do this such as ReentrantLock. This object comes with methods which allow locking/unlocking across multiple methods. Alongside this, it comes with an optional fairness parameter. This gives you some control over how to distribute lock access to different threads.
Another key feature, is lock polling. The built in methods allow you to test the lock to see if it is available from one method.

--

--