|
@@ -0,0 +1,56 @@
|
|
|
|
|
+package leetcode.p1226;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.concurrent.locks.ReentrantLock;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @ProjectName: LeetCode
|
|
|
|
|
+ * @FileName: DiningPhilosophers
|
|
|
|
|
+ * @Author: 杨逸
|
|
|
|
|
+ * @Data:2026/3/28 12:36
|
|
|
|
|
+ * @Description: https://leetcode.cn/problems/the-dining-philosophers/
|
|
|
|
|
+ * 1226. 哲学家进餐
|
|
|
|
|
+ */
|
|
|
|
|
+public class DiningPhilosophers {
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 需要避免死锁
|
|
|
|
|
+ * 使用五把锁表示五把叉子
|
|
|
|
|
+ */
|
|
|
|
|
+ public static final ReentrantLock[] forks = new ReentrantLock[5];
|
|
|
|
|
+ static {
|
|
|
|
|
+ for (int i = 0; i < 5; i++)
|
|
|
|
|
+ forks[i] = new ReentrantLock();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public DiningPhilosophers() {
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 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 {
|
|
|
|
|
+ boolean flag = false;
|
|
|
|
|
+ int left = philosopher;
|
|
|
|
|
+ int right = (philosopher + 1) % 5;
|
|
|
|
|
+ while(!flag) {
|
|
|
|
|
+ if (forks[left].tryLock()){
|
|
|
|
|
+ //获取左边的叉子
|
|
|
|
|
+ if (forks[right].tryLock()) {
|
|
|
|
|
+ //获取右边的叉子
|
|
|
|
|
+ pickLeftFork.run();
|
|
|
|
|
+ pickRightFork.run();
|
|
|
|
|
+ eat.run();
|
|
|
|
|
+ putLeftFork.run();
|
|
|
|
|
+ putRightFork.run();
|
|
|
|
|
+ forks[right].unlock();
|
|
|
|
|
+ flag = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ forks[left].unlock();
|
|
|
|
|
+ }
|
|
|
|
|
+ Thread.yield();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|