Skip to content
DeveloperMemos

Synchronized vs Lock in Kotlin

Kotlin, Concurrency1 min read

When it comes to writing concurrent code in Kotlin, two of the most common approaches are using synchronized blocks and Lock. Although both these methods aim to provide thread-safety, they have some significant differences.

What is synchronized?

synchronized is a keyword in Kotlin used to enforce mutual exclusion of threads. When a block of code is marked as synchronized, only one thread can execute that block at a time, and all other threads attempting to access it have to wait until the lock is released.

Here's an example of how to use synchronized:

1class Counter {
2 private var count = 0
3
4 fun increment() {
5 synchronized(this) {
6 count++
7 }
8 }
9
10 fun getCount(): Int {
11 synchronized(this) {
12 return count
13 }
14 }
15}

In the above code, the increment() and getCount() functions are synchronized on the current instance of the Counter class, which ensures that only one thread can access them at a time.

What is Lock?

Lock is an interface in Kotlin that allows more fine-grained control over thread synchronization than synchronized blocks. Lock provides a range of locking methods like lock(), unlock(), tryLock() etc., which can be used to acquire and release locks with more flexibility.

Here's an example of how to use Lock:

1class Counter {
2 private var count = 0
3 private val lock = ReentrantLock()
4
5 fun increment() {
6 lock.lock()
7 try {
8 count++
9 } finally {
10 lock.unlock()
11 }
12 }
13
14 fun getCount(): Int {
15 lock.lock()
16 try {
17 return count
18 } finally {
19 lock.unlock()
20 }
21 }
22}

In the above code, we are using ReentrantLock to create a lock object that can be acquired and released using lock() and unlock() methods. We are also using a try-finally block to ensure that the lock is released even if an exception occurs.

Key Differences between synchronized and Lock

Although both these methods accomplish similar tasks, there are some differences between them:

  • Fine-grained control: As mentioned earlier, Lock provides more fine-grained control over thread synchronization than synchronized.

  • Interruptible: Unlike synchronized, Lock supports interruption, which means that a thread waiting for a lock can be interrupted and resume execution.

  • Fairness: Lock allows you to choose whether to use a fair or unfair locking mechanism while synchronized always uses a fair locking mechanism.

  • Readability: synchronized blocks are easier to read and understand compared to Lock, which requires more code to acquire and release locks.

Summary

In summary, both synchronized and Lock are useful tools for writing concurrent code in Kotlin, and the choice between them depends on the specific requirements of your application. If you need finer-grained control over thread synchronization or support for interruption Lock is a good choice. On the other hand, if you want a simpler and more readable approach synchronized is a better option.