私は、 を通じて公正および非公正な規律をテストされましRentrantLock
た。食事の哲学者をシミュレートする小さなプログラムを書きました。
各哲学者には、s である左右のフォークがありますReentrantLock
。私は1000回の思考と食事の行為をシミュレートしました:
for (int i = 0; i < ACT_TIMES; i++) {
act();
}
どこact
ですか
private void act() {
think();
eat();
}
Think
面白くありません。しばらくスリープするだけです。ここにeat
方法があります
private void eat() {
try {
if (left.tryLock(0, TimeUnit.MILLISECONDS)) {
if (right.tryLock(0, TimeUnit.MILLISECONDS)) {
log("eating");
eatCount++;
try {
Thread.sleep(EAT_TIME);
} catch (InterruptedException e) {
} finally {
left.unlock();
right.unlock();
}
} else {
left.unlock();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
主な方法:
Lock[] forks = new Lock[5];
for (int i = 0; i < forks.length; i++) {
forks[i] = new ReentrantLock();
}
Philosopher p1 = new Philosopher(0, forks[1], forks[0]);
Philosopher p2 = new Philosopher(1, forks[2], forks[1]);
Philosopher p3 = new Philosopher(2, forks[3], forks[2]);
Philosopher p4 = new Philosopher(3, forks[4], forks[3]);
Philosopher p5 = new Philosopher(4, forks[0], forks[4]);
ExecutorService exec = Executors.newFixedThreadPool(5);
exec.submit(p1);
exec.submit(p2);
exec.submit(p3);
exec.submit(p4);
exec.submit(p5);
5 つのスレッドがすべて終了したら、哲学者ごとに eatCount を出力します。new ReentrantLock(true)
そして、これらの値は、fair( ) と unfair( new ReentrantLock()
) の規律でそれほど違いはありません。
(最初の数字は哲学者の数字です)
フェアロック:
0 344
1 348
2 366
3 359
4 363
Total number of eating 1780
不公平なロック:
0 338
1 338
2 339
3 341
4 352
Total number of eating 1708
私は、不公平なロックのために飢餓が発生することを予想していました。つまり、何人かの哲学者/哲学者は他の人よりもはるかに多くの eatCount を持たなければなりませんでしたが、飢餓は起こりませんでした。なぜ?