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

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:

主站蜘蛛池模板: 商都县| 崇阳县| 洱源县| 张家口市| 偏关县| 日土县| 新乡市| 安平县| 区。| 临沭县| 八宿县| 即墨市| 兰州市| 东平县| 玉树县| 舞阳县| 元江| 江陵县| 兴海县| 静宁县| 乐亭县| 开封市| 睢宁县| 湘潭县| 芦山县| 墨脱县| 八宿县| 洛扎县| 台北市| 水城县| 牟定县| 日土县| 连平县| 得荣县| 兴文县| 祁东县| 绍兴县| 巴林右旗| 崇阳县| 牡丹江市| 安平县|