philosophers are fed
This commit is contained in:
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user