philosophers are fed
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
|
||||||
class Fork(id: String) : Observable<String?>(id) {
|
class Fork(id: String) : Observable<String?>(id) {
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
// --------------- EDIT CODE BELOW ---------------
|
// --------------- EDIT CODE BELOW ---------------
|
||||||
|
val mutex = Mutex()
|
||||||
|
|
||||||
suspend fun take(philosopher: String) {
|
suspend fun take(philosopher: String) {
|
||||||
setOccupiedBy(philosopher)
|
setOccupiedBy(philosopher)
|
||||||
@@ -13,6 +15,7 @@ class Fork(id: String) : Observable<String?>(id) {
|
|||||||
|
|
||||||
suspend fun release() {
|
suspend fun release() {
|
||||||
setOccupiedBy(null)
|
setOccupiedBy(null)
|
||||||
|
mutex.unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------- EDIT CODE ABOVE ---------------
|
// --------------- EDIT CODE ABOVE ---------------
|
||||||
@@ -33,20 +36,46 @@ class Philosopher(
|
|||||||
private val leftFork: Fork,
|
private val leftFork: Fork,
|
||||||
private val rightFork: Fork,
|
private val rightFork: Fork,
|
||||||
) : Observable<String>(id) {
|
) : Observable<String>(id) {
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
// --------------- EDIT CODE BELOW ---------------
|
// --------------- EDIT CODE BELOW ---------------
|
||||||
|
|
||||||
suspend fun start() = repeat(10) {
|
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() {
|
private suspend fun takeForks() {
|
||||||
leftFork.take(id)
|
leftFork.take(id)
|
||||||
rightFork.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() {
|
private suspend fun wait() {
|
||||||
delay(1)
|
delay(1)
|
||||||
@@ -94,7 +123,7 @@ suspend fun main(args: Array<String>) = runBlocking {
|
|||||||
}
|
}
|
||||||
forks.forEach {
|
forks.forEach {
|
||||||
it.onChange = { fork, philosopher ->
|
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 {
|
init {
|
||||||
coroutineDebugProbes = true
|
coroutineDebugProbes = true
|
||||||
timeout = 2000
|
|
||||||
val philosopherNumbers = listOf(2, 5, 12).exhaustive()
|
val philosopherNumbers = listOf(2, 5, 12).exhaustive()
|
||||||
|
|
||||||
|
|
||||||
@@ -59,13 +58,13 @@ class DiningPhilosophersTest : StringSpec() {
|
|||||||
diningPhilosopherLogger.send(ReadLogMessage(response))
|
diningPhilosopherLogger.send(ReadLogMessage(response))
|
||||||
|
|
||||||
response.await()
|
response.await()
|
||||||
.filter { it.first.contains("Philosophers") }
|
.filter { it.first.contains("Philosopher") }
|
||||||
.filter { it.second == "THINKING" }
|
.filter { it.second == "THINKING" }
|
||||||
.groupBy { it.first }
|
.groupBy { it.first }
|
||||||
.apply {
|
.apply {
|
||||||
size shouldBe n
|
size shouldBe n
|
||||||
forEach {
|
forEach {
|
||||||
it.value.size shouldBe n
|
it.value.size shouldBe 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user