synchronized 位置问题
来源:5-14 高阶并发编程Coding训练:N种优化哲学家就餐问题的方法(2)

HotChoc
2021-06-07
老师,synchronized 是不是不应该加在两个 Overide 的 take 方法上,那样锁住的是每个 Phi 实例,对于 forks 不能起到保护作用吧?
下面是我的代码
public class DiningPhilosophersDeadLock {
Phi[] phis;
volatile int[] forks;
static final int NUM = 5;
final Object lock = new Object();
public DiningPhilosophersDeadLock() {
phis = new Phi[NUM];
forks = new int[NUM];
for (int i = 0; i < NUM; i++) {
phis[i] = new Phi(i + 1);
}
}
class Phi extends Philosopher {
Phi(int id) {
super(id);
}
@Override
protected boolean takeLeft(int[] forks) {
synchronized (lock) {
return super.takeLeft(forks);
}
}
@Override
protected boolean takeRight(int[] forks) {
synchronized (lock) {
return super.takeRight(forks);
}
}
@Override
public void run() {
while (true) {
try {
thinking();
while (!takeLeft(forks)) {
Thread.onSpinWait();
}
// System.out.println("take left");
Thread.sleep(100);
int c = 0;
// 这种方法虽然解决了 dead lock, 但小概率可能触发 live lock(所有线程都拿起了左叉子, 然后一起放下)
while (!takeRight(forks)) {
if (++c > 100) {
putLeft(forks);
continue;
}
Thread.onSpinWait();
}
// System.out.println("take right");
eating();
putLeft(forks);
putRight(forks);
finish();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void run() {
ExecutorService pool = Executors.newFixedThreadPool(NUM);
for (Phi phi : phis) {
pool.submit(phi);
}
}
public static void main(String[] args) {
DiningPhilosophersDeadLock solver = new DiningPhilosophersDeadLock();
solver.run();
}
}
写回答
2回答
-
weixin_慕少1467281
2023-09-07
这个课程的代码真是一堆问题,字符串判断直接用 == ,我都要傻眼了00 -
求老仙
2021-06-25
现在的锁相当于所有phi对象公用的。保护的是forks数组。
00
相似问题