Add thread safe data structures code
This commit is contained in:
168
DataStructures/ThreadSafeDataStructures2.kt
Normal file
168
DataStructures/ThreadSafeDataStructures2.kt
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* This Kotlin source file was generated by the Gradle 'init' task.
|
||||||
|
*/
|
||||||
|
package threadsafe
|
||||||
|
|
||||||
|
import io.kotest.core.spec.style.StringSpec
|
||||||
|
import kotlinx.coroutines.asCoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.junit.jupiter.api.assertThrows
|
||||||
|
import java.util.Collections
|
||||||
|
import java.util.Hashtable
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
val dispatcher = Executors.newCachedThreadPool().asCoroutineDispatcher()
|
||||||
|
|
||||||
|
class LibraryTest : StringSpec({
|
||||||
|
"CountDownLatch" {
|
||||||
|
withContext(dispatcher) {
|
||||||
|
val createdValues = mutableListOf<Int>()
|
||||||
|
val countDownLatch = CountDownLatch(3)
|
||||||
|
|
||||||
|
(1..5).forEach { index ->
|
||||||
|
launch {
|
||||||
|
delay(Random.nextLong(0, 100))
|
||||||
|
createdValues.add(index)
|
||||||
|
println("Added value $index")
|
||||||
|
countDownLatch.countDown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(1..3).forEach { _ ->
|
||||||
|
launch {
|
||||||
|
countDownLatch.await()
|
||||||
|
println("The sum is ${createdValues.sum()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"Non-blocking CountDownLatch" {
|
||||||
|
withContext(dispatcher) {
|
||||||
|
val createdValues = mutableListOf<Int>()
|
||||||
|
val countDownLatch = CountDownLatch(3)
|
||||||
|
|
||||||
|
(1..5).forEach { index ->
|
||||||
|
launch {
|
||||||
|
delay(Random.nextLong(0, 100))
|
||||||
|
createdValues.add(index)
|
||||||
|
println("Added value $index")
|
||||||
|
countDownLatch.countDown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (countDownLatch.count > 0) {
|
||||||
|
delay(10)
|
||||||
|
}
|
||||||
|
println("The sum is ${createdValues.sum()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"SynchronizedList" {
|
||||||
|
withContext(dispatcher) {
|
||||||
|
val unsyncList = mutableListOf<Int>()
|
||||||
|
coroutineScope {
|
||||||
|
(1..10000).forEach { index ->
|
||||||
|
launch {
|
||||||
|
unsyncList.add(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("Unsync list size: ${unsyncList.size}")
|
||||||
|
|
||||||
|
val syncList = Collections.synchronizedList(mutableListOf<Int>())
|
||||||
|
coroutineScope {
|
||||||
|
(1..10000).forEach { index ->
|
||||||
|
launch {
|
||||||
|
syncList.add(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("Sync list size: ${syncList.size}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"CopyOnWriteArrayList" {
|
||||||
|
withContext(dispatcher) {
|
||||||
|
val ordinaryList = Collections.synchronizedList((1..10000).toMutableList())
|
||||||
|
launch {
|
||||||
|
delay(5)
|
||||||
|
var maximum = 0
|
||||||
|
assertThrows<ConcurrentModificationException> {
|
||||||
|
for (number in ordinaryList) {
|
||||||
|
maximum = max(number, maximum)
|
||||||
|
}
|
||||||
|
println("The maximum is: $maximum")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(20000..25000).forEach {
|
||||||
|
launch {
|
||||||
|
ordinaryList.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val copyOnWriteList = CopyOnWriteArrayList((1..10000).toMutableList())
|
||||||
|
launch {
|
||||||
|
delay(5)
|
||||||
|
var maximum = 0
|
||||||
|
for (number in copyOnWriteList) {
|
||||||
|
if (number == 1) {
|
||||||
|
println("Starting to compare")
|
||||||
|
}
|
||||||
|
maximum = max(number, maximum)
|
||||||
|
}
|
||||||
|
println("The maximum is: $maximum")
|
||||||
|
}
|
||||||
|
(20000..25000).forEach { number ->
|
||||||
|
launch {
|
||||||
|
println("Adding $number")
|
||||||
|
copyOnWriteList.add(number)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"HashTable" {
|
||||||
|
withContext(dispatcher) {
|
||||||
|
val hashTable = Hashtable<String, Int>()
|
||||||
|
(1..10).forEach { number ->
|
||||||
|
launch {
|
||||||
|
println("Inserting key=$number")
|
||||||
|
hashTable["key"] = number
|
||||||
|
println("Inserted key=$number")
|
||||||
|
}
|
||||||
|
launch {
|
||||||
|
println("Inserting other=$number")
|
||||||
|
hashTable["other"] = number
|
||||||
|
println("Inserted other=$number")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"ConcurrentHashMap" {
|
||||||
|
withContext(dispatcher) {
|
||||||
|
val hashMap = ConcurrentHashMap<String, Int>()
|
||||||
|
(1..10).forEach { number ->
|
||||||
|
launch {
|
||||||
|
println("Inserting key=$number")
|
||||||
|
hashMap["key"] = number
|
||||||
|
println("Inserted key=$number")
|
||||||
|
}
|
||||||
|
launch {
|
||||||
|
println("Inserting other=$number")
|
||||||
|
hashMap["other"] = number
|
||||||
|
println("Inserted other=$number")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user