/* * 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() 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() 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() coroutineScope { (1..10000).forEach { index -> launch { unsyncList.add(index) } } } println("Unsync list size: ${unsyncList.size}") val syncList = Collections.synchronizedList(mutableListOf()) 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 { 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() (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() (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") } } } } })