RosettaCodeData/Task/Dining-philosophers/Groovy/dining-philosophers.groovy
2014-01-17 05:34:36 +00:00

56 lines
1.3 KiB
Groovy

import groovy.transform.Canonical
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
@Canonical
class Fork {
String name
Lock lock = new ReentrantLock()
void pickUp(String philosopher) {
lock.lock()
println " $philosopher picked up $name"
}
void putDown(String philosopher) {
lock.unlock()
println " $philosopher put down $name"
}
}
@Canonical
class Philosopher extends Thread {
Fork f1
Fork f2
@Override
void run() {
def random = new Random()
(1..20).each { bite ->
println "$name is hungry"
f1.pickUp name
f2.pickUp name
println "$name is eating bite $bite"
Thread.sleep random.nextInt(300) + 100
f2.putDown name
f1.putDown name
}
}
}
void diningPhilosophers(names) {
def forks = (1..names.size()).collect { new Fork(name: "Fork $it") }
def philosophers = []
names.eachWithIndex{ n, i ->
def (i1, i2) = [i, (i + 1) % 5]
if (i2 < i1) (i1, i2) = [i2, i]
def p = new Philosopher(name: n, f1: forks[i1], f2: forks[i2])
p.start()
philosophers << p
}
philosophers.each { it.join() }
}
diningPhilosophers(['Aristotle', 'Kant', 'Spinoza', 'Marx', 'Russell'])