爱喝咖啡的程序员 2020-01-12 17:37 采纳率: 0%
浏览 215

Java编程思想 哲学家问题 为什么为哲学家增加思考的时间,就能缓解死锁的产生?

我十分不解,为什么在Philosopher类中的run()内增加pause()就能让死锁慢一点发生?请大神指教

这个例子中,产生死锁的原因在于,所有的哲学家都拿到了右筷子,却因为拿不到左筷子而陷入循环等待。但这和是否使用pause()有关系吗?可以注意到例子中使用的随机数赋予了种子,也就是说,每次运行得到的结果是一个固定且相同的值,即便是加了pause(),等待哪怕1000秒,当1000秒后,所有的哲学家仍然同时由等待状态转变成了可运行态,接着受到线程调度器分配时间片来驱动,这和等待时间的长短又有什么必然的关系呢???(ps: 我的理解是把种子去掉,不同的哲学家思考的时间不同,进入"拿筷子"阶段的时间不同,**降低同时请求共享资源的可能性**,这样倒是能缓解死锁发生的概率,书上的说法实在是无法理解)

请先避开不谈满足死锁的四个条件。直接讨论这个例子。

/**
 * 哲学家问题 筷子
 */
public class Chopstick {
    private boolean taken = false;
    public synchronized void take(int id, String direction) throws InterruptedException{
        while(taken) {
            System.out.println("Philosopher " + id + " waiting " + direction + " chopstick");
            this.wait();
        }
        // 现在由新的哲学家持有这根筷子
        taken = true;
        System.out.println("Philosopher " + id + " grabbed " + direction + " chopstick");
    }
    public synchronized void drop() {
        taken = false;
        this.notifyAll();
    }
}
/**
 * 哲学家问题 哲学家
 */
public class Philosopher implements Runnable{
    private Chopstick left;
    private Chopstick right;
    private final int id;
    private final int ponderFactor;
    private Random rand = new Random(47);

    private void pause() throws InterruptedException{
        if(ponderFactor == 0) {
            return;
        }
        TimeUnit.MILLISECONDS.sleep(rand.nextInt(ponderFactor * 250));
    }

    public Philosopher(Chopstick left, Chopstick right, int ident, int ponder) {
        this.left = left;
        this.right = right;
        this.id = ident;
        this.ponderFactor = ponder;
    }

    @Override
    public void run() {
        try {
            while(!Thread.interrupted()) {
                // 为什么加上的等待时间越长,产生死锁的可能性越小?
                pause();
                //System.out.println(this + " beginning eating " + LocalDateTime.now().getNano());
                // 哲学家开始变饿
                System.out.println(this + " " + "grabbing right");
                right.take(id, "right");
                System.out.println(this + " " + "grabbing left");
                left.take(id, "left");
                System.out.println(this + " " + "eating");
                pause();
                right.drop();
                left.drop();
            }
        }catch (InterruptedException e) {
            System.out.println(this + " " + "exiting via interrupt");
        }
    }

    public String toString() {
        return "Philosopher " + id;
    }
}
/**
 * 哲学家问题 演示死锁
 */
public class DeadlockingDiningPhilosopher {
    public static void main(String[] args) throws InterruptedException, IOException {
        int ponder = 5;
        if(args.length > 0) {
            ponder = Integer.parseInt(args[0]);
        }
        int size = 5;
        if (args.length > 1) {
            size = Integer.parseInt(args[1]);
        }

        ExecutorService exec = Executors.newCachedThreadPool();
        Chopstick[] sticks = new Chopstick[size];

        for(int i = 0; i < size; i++) {
            sticks[i] = new Chopstick();
        }

        for (int i = 0; i < size; i++) {
            exec.execute(new Philosopher(sticks[i], sticks[(i+1) % size], i, ponder));
        }

        if (args.length == 3 && args[2].equals("timeout")) {
            TimeUnit.SECONDS.sleep(5);
        } else {
            System.out.println("Press 'Enter' to quit");
            System.in.read();
        }
        exec.shutdownNow();
    }
}
  • 写回答

1条回答 默认 最新

  • 日落西风又在吹 2023-10-25 17:17
    关注

    等待时间越长别人用完资源归还锁的可能性越大进入死锁的几率越小是正常的

    评论

报告相同问题?

悬赏问题

  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决