Skip to content

Instantly share code, notes, and snippets.

@L-Briand
Created February 14, 2024 08:33
Show Gist options
  • Save L-Briand/fc4ed6fffa524dc146705a86f34624e2 to your computer and use it in GitHub Desktop.
Save L-Briand/fc4ed6fffa524dc146705a86f34624e2 to your computer and use it in GitHub Desktop.
Resource sharing with semaphore and mutex in kotlin
/**
* 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