— Kotlin, Concurrency — 1 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.
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 = 03
4 fun increment() {5 synchronized(this) {6 count++7 }8 }9
10 fun getCount(): Int {11 synchronized(this) {12 return count13 }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.
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 = 03 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 count18 } 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.
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.
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.