Alex Kuznetsov
03/19/2024, 6:34 PMEmil Kantis
03/19/2024, 6:54 PMAlex Kuznetsov
03/19/2024, 6:58 PMval nextValue = sharedMutableInt++
as opposed to
val nextValue = myAtomicInt.incrementAndGet()
I have my own code that does it, but it is not fully bakedEmil Kantis
03/19/2024, 6:59 PMAlex Kuznetsov
03/19/2024, 7:00 PMAlex Kuznetsov
03/19/2024, 7:01 PMAlex Kuznetsov
03/19/2024, 7:01 PMAlex Kuznetsov
03/19/2024, 7:09 PM"demo for mockkStatic".config(enabled = true) {
runInParallel({ runner: ParallelRunner ->
timedPrint("Before mock on same thread: ${LocalDateTime.now().toString()}")
runner.await()
mockkStatic(LocalDateTime::class)
val localTime = LocalDateTime.of(2022, 4, 27, 12, 34, 56)
every { LocalDateTime.now(any<Clock>()) } returns localTime
runner.await()
timedPrint("After mock on same thread: ${LocalDateTime.now().toString()}")
},
{ runner: ParallelRunner ->
timedPrint("Before mock on other thread: ${LocalDateTime.now().toString()}")
runner.await()
runner.await()
timedPrint("After mock on other thread: ${LocalDateTime.now().toString()}")
}
)
/*
Time: 2023-05-12T13:14:07.815923, Thread: 51, Before mock on other thread: 2023-05-12T13:14:07.737748
Time: 2023-05-12T13:14:07.816011, Thread: 50, Before mock on same thread: 2023-05-12T13:14:07.737736
Time: 2022-04-27T12:34:56, Thread: 51, After mock on other thread: 2022-04-27T12:34:56
Time: 2022-04-27T12:34:56, Thread: 50, After mock on same thread: 2022-04-27T12:34:56
*/
}
with the following implementation:
import java.util.concurrent.CyclicBarrier
import java.util.concurrent.TimeUnit
import kotlin.concurrent.thread
class ParallelRunner(
private val timeoutInMs: Long,
vararg tasks: (runner: ParallelRunner) -> Unit) {
private val tasks = tasks.toList()
private val barrier = CyclicBarrier(tasks.size)
constructor(vararg tasks: (runner: ParallelRunner) -> Unit): this(1000L, *(tasks))
fun run() {
val threads = tasks.map { task ->
thread(start = false) {
task(this)
}
}
threads.forEach { it.start() }
threads.forEach { it.join() }
}
fun await() = barrier.await(timeoutInMs, TimeUnit.MILLISECONDS)
companion object {
fun runInParallel(vararg tasks: (runner: ParallelRunner) -> Unit) {
ParallelRunner(*(tasks)).run()
}
}
}
Emil Kantis
03/19/2024, 7:14 PMAlex Kuznetsov
03/19/2024, 7:26 PMParallelRunner
- demo shows how to use it, there are several more demos using it. I also have another class for reproducing deadlocks, dirty reads etc.Emil Kantis
03/19/2024, 7:29 PMEmil Kantis
03/19/2024, 7:31 PMAlex Kuznetsov
03/19/2024, 7:36 PMEmil Kantis
03/19/2024, 7:38 PMAlex Kuznetsov
03/19/2024, 7:51 PMEmil Kantis
03/19/2024, 7:56 PMAlex Kuznetsov
03/19/2024, 8:08 PMCLOVIS
03/20/2024, 9:05 AMAlex Kuznetsov
03/20/2024, 2:03 PMCLOVIS
03/20/2024, 2:04 PMOliver.O
03/21/2024, 4:32 PMEmil Kantis
03/21/2024, 4:33 PMOliver.O
03/21/2024, 4:34 PMEmil Kantis
03/21/2024, 4:52 PMOliver.O
03/21/2024, 5:21 PMAlex Kuznetsov
03/21/2024, 5:47 PMOliver.O
03/21/2024, 6:40 PMOliver.O
03/21/2024, 6:49 PMAlex Kuznetsov
03/21/2024, 6:53 PMOliver.O
03/21/2024, 7:06 PMThreadLocal
which does not work with a thread-hopping coroutine, ...Alex Kuznetsov
03/21/2024, 7:18 PM