diff --git a/DataStructures/ThreadSafeDataStructures2.kt b/DataStructures/ThreadSafeDataStructures2.kt new file mode 100644 index 0000000..adb7dce --- /dev/null +++ b/DataStructures/ThreadSafeDataStructures2.kt @@ -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() + 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") + } + } + } + } +})