- Functional Kotlin
- Mario Arias Rivu Chakraborty
- 384字
- 2021-06-24 19:15:29
Thread safety
We have probably seen a thousand times that immutability brings thread safety to the table along with it. What does it actually mean and how does immutability achieve thread safety? Working with multiple threads is itself a complex job. When you are accessing a class from multiple threads, you need to ensure certain things, like locking and releasing of the object and synchronization, but none of them are required if you are accessing any immutable data from multiple threads.
Confused? Let's have an example with threads and mutable data:
class MyData { var someData:Int = 0 } fun main(args: Array<String>) { val myData:MyData = MyData() async(CommonPool) { for(i in 11..20) { myData.someData+=i println("someData from 1st async ${myData.someData}") delay(500) } } async(CommonPool) { for(i in 1..10) { myData.someData++ println("someData from 2nd async ${myData.someData}") delay(300) } } runBlocking { delay(10000) } }
In this program, we've used two coroutines (we will cover coroutines in detail in Chapter 7, Asynchronous Processing with Coroutines) which works on the same mutable data. Let's have a look in the following output and then we will describe and discuss the problems in this program:

So, look closely at the output. As both the coroutines works simultaneously on myData.someData, data consistency is not ensured in either one.
The traditional solution to this problem is to use locking-releasing techniques and synchronization, but then also you'll need to write a lot of code for that and to avoid deadlock while implementing locking and releasing of data.
Functional programming provides a one-stop solution to this problem through immutability. Let's have a look how immutability and local variables can save you in multithreading:
class MyDataImmutable { val someData:Int = 0 } fun main(args: Array<String>) { val myData: MyDataImmutable = MyDataImmutable() async(CommonPool) { var someDataCopy = myData.someData for (i in 11..20) { someDataCopy += i println("someData from 1st async $someDataCopy") delay(500) } } async(CommonPool) { var someDataCopy = myData.someData for (i in 1..10) { someDataCopy++ println("someData from 2nd async $someDataCopy") delay(300) } } runBlocking { delay(10000) } }
We've modified the previous program to make someData immutable (as we're not using custom getter with this variable, so it will remain immutable) and used local variables inside both the coroutines.
Have a look at the following output; it clearly shows that the problem is solved:

- Dynamics 365 Application Development
- Learning Data Mining with Python
- 程序員數學:用Python學透線性代數和微積分
- Oracle 12c中文版數據庫管理、應用與開發實踐教程 (清華電腦學堂)
- NumPy Essentials
- Python Tools for Visual Studio
- Python Network Programming Cookbook(Second Edition)
- QGIS By Example
- 零基礎學Kotlin之Android項目開發實戰
- INSTANT Apache Hive Essentials How-to
- Python數據預處理技術與實踐
- Developer,Advocate!
- Learning NHibernate 4
- Instant AppFog
- 微信公眾平臺服務號開發:揭秘九大高級接口