官术网_书友最值得收藏!

  • 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 7Asynchronous 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:

主站蜘蛛池模板: 东阳市| 安福县| 漳浦县| 桦甸市| 百色市| 万源市| 陇南市| 明星| 正镶白旗| 清新县| 苗栗县| 赤壁市| 建阳市| 巴马| 商南县| 碌曲县| 武川县| 达拉特旗| 晋中市| 兰州市| 玉溪市| 镇坪县| 孟州市| 鄂尔多斯市| 吴江市| 女性| 新龙县| 尤溪县| 循化| 策勒县| 宁都县| 日喀则市| 乐陵市| 佛学| 定远县| 比如县| 呼和浩特市| 都江堰市| 博湖县| 惠东县| 阿城市|