/
Solution1226.java
88 lines (80 loc) · 2.87 KB
/
Solution1226.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package com.gitee.passerr.leetcode.problem.concurrency.page1;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.stream.IntStream;
/**
* Solution1226
* @author xiehai
* @date 2023/08/18 09:35
*/
public class Solution1226 {
public void execute(int n) {
ExecutorService service = Executors.newFixedThreadPool(5);
DiningPhilosophers philosophers = new DiningPhilosophers();
CountDownLatch count = new CountDownLatch(5 * n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < 5; j++) {
final int index = j;
service.execute(() -> {
try {
philosophers.wantsToEat(
index,
() -> System.out.printf("[%d, 1, 1], ", index),
() -> System.out.printf("[%d, 2, 1], ", index),
() -> System.out.printf("[%d, 0, 3], ", index),
() -> System.out.printf("[%d, 1, 2], ", index),
() -> System.out.printf("[%d, 2, 2], ", index)
);
} catch (InterruptedException ignore) {
} finally {
count.countDown();
}
});
}
}
try {
count.await();
} catch (InterruptedException ignore) {
}
}
}
// #region snippet
class DiningPhilosophers {
/**
* 假设哲学家按照题目描述编号,p0、p1、p2、p3、p4
* 叉子编号为f0、f1、f2、f3、f4
* 叉子和哲学家位置关系 f0p0f1p1f2p2f3p3f4p4f0p0....
*/
Semaphore[] forks = new Semaphore[5];
/**
* 最多同时允许4个人用餐
*/
Semaphore philosophers;
public DiningPhilosophers() {
// 叉子信号量准备
IntStream.range(0, forks.length).forEach(it -> this.forks[it] = new Semaphore(1));
// 用餐人数信号量
this.philosophers = new Semaphore(4);
}
// call the run() method of any runnable to execute its code
public void wantsToEat(int philosopher, Runnable pickLeftFork, Runnable pickRightFork, Runnable eat,
Runnable putLeftFork, Runnable putRightFork) throws InterruptedException {
this.philosophers.acquire();
Semaphore left = this.forks[(philosopher + 1) % 5], right = this.forks[philosopher];
left.acquire();
right.acquire();
pickLeftFork.run();
pickRightFork.run();
eat.run();
// 叉子释放
putRightFork.run();
right.release();
putLeftFork.run();
left.release();
// 用餐人数释放
this.philosophers.release();
}
}
// #endregion snippet