Created
February 14, 2024 08:33
-
-
Save L-Briand/fc4ed6fffa524dc146705a86f34624e2 to your computer and use it in GitHub Desktop.
Resource sharing with semaphore and mutex in kotlin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Thread safe shared resources. | |
* | |
* ```kotlin | |
* // await 1s with the resource | |
* fun run(pool: ResourcePool<*>) = launch { pool { delay(1.seconds) } } | |
* | |
* // Pool of 2 usable elements at the same time | |
* val pool = ResourcePool<Unit>(2) { Unit } | |
* (0 ..< 120).map { run(pool) }.joinAll() // elapsed time ~60s | |
* | |
* // Pool of 4 usable elements at the same time | |
* val pool = ResourcePool<Unit>(4) { Unit } | |
* (0 ..< 120).map { run(pool) }.joinAll() // elapsed time ~30s | |
* ``` | |
*/ | |
class ResourcePool<out T>(count: Int, factory: (Int) -> T) : Closeable { | |
private val mutex = Mutex() | |
private val semaphore = Semaphore(count) | |
private val resources = MutableList(count, factory) | |
suspend operator fun <R> invoke(handler: suspend (T) -> R): R { | |
semaphore.withPermit { | |
val borrowed = mutex.withLock { resources.removeLast() } | |
try { | |
return handler(borrowed) | |
} finally { | |
mutex.withLock { resources.add(borrowed) } | |
} | |
} | |
} | |
override fun close() { | |
resources.clear() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment