philosophers are fed

This commit is contained in:
2022-09-29 15:18:31 +02:00
parent 883035f5d6
commit efc2fcb2a9
2 changed files with 35 additions and 7 deletions

View File

@@ -1,11 +1,13 @@
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
class Fork(id: String) : Observable<String?>(id) {
//TODO
// --------------- EDIT CODE BELOW ---------------
val mutex = Mutex()
suspend fun take(philosopher: String) {
setOccupiedBy(philosopher)
@@ -13,6 +15,7 @@ class Fork(id: String) : Observable<String?>(id) {
suspend fun release() {
setOccupiedBy(null)
mutex.unlock()
}
// --------------- EDIT CODE ABOVE ---------------
@@ -33,20 +36,46 @@ class Philosopher(
private val leftFork: Fork,
private val rightFork: Fork,
) : Observable<String>(id) {
//TODO
// --------------- EDIT CODE BELOW ---------------
suspend fun start() = repeat(10) {
think()
while (true) {
if (leftFork.mutex.tryLock(id) && rightFork.mutex.tryLock(id)) {
takeForks()
break
} else {
println("phil $id has left fork locked : ${leftFork.mutex.isLocked}")
println("phil $id has right fork locked : ${rightFork.mutex.isLocked}")
if (leftFork.mutex.holdsLock(id)) {
leftFork.mutex.unlock(id)
}
if (rightFork.mutex.holdsLock(id)) {
rightFork.mutex.unlock(id)
}
wait()
}
}
}.also { changeState("FINISHED") }
eat()
releaseForksAndUnlock()
}.also {
changeState("FINISHED")
}
private suspend fun takeForks() {
leftFork.take(id)
rightFork.take(id)
println("phil $id has taken forks")
}
private suspend fun releaseForksAndUnlock() {
leftFork.release()
rightFork.release()
println("phil $id has released forks")
}
// --------------- EDIT CODE ABOVE ---------------
// --------------- EDIT CODE ABOVE ---------------
private suspend fun wait() {
delay(1)
@@ -94,7 +123,7 @@ suspend fun main(args: Array<String>) = runBlocking {
}
forks.forEach {
it.onChange = { fork, philosopher ->
println(philosopher?.let { "$fork acquired by $it" } ?: "$fork released")
println(philosopher?.let { "$philosopher $fork acquired by $it" } ?: "$philosopher $fork released")
}
}

View File

@@ -20,7 +20,6 @@ class DiningPhilosophersTest : StringSpec() {
init {
coroutineDebugProbes = true
timeout = 2000
val philosopherNumbers = listOf(2, 5, 12).exhaustive()
@@ -59,13 +58,13 @@ class DiningPhilosophersTest : StringSpec() {
diningPhilosopherLogger.send(ReadLogMessage(response))
response.await()
.filter { it.first.contains("Philosophers") }
.filter { it.first.contains("Philosopher") }
.filter { it.second == "THINKING" }
.groupBy { it.first }
.apply {
size shouldBe n
forEach {
it.value.size shouldBe n
it.value.size shouldBe 10
}
}