5个哲学家吃饭问题怎么解决?且有效率的解决?

发布于 2022-09-12 03:10:30 字数 3120 浏览 15 评论 0

请问这种场景用什么办法可以避免死锁?且效率比较高
`

package com.yh.test.thread.locks;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Description: 死锁模拟
 * @Author: 张颖辉(yh)
 * @CreateDate: 2020/6/9 14:01
 * @UpdateUser: 张颖辉(yh)
 * @UpdateDate: 2020/6/9 14:01
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
public class DeadLock {
    /*
     * 5个哲学家吃饭问题
     * 场景:一个圆桌子,周围做了5个哲学家,每人两边分别有一支筷子,一共5支.
     * 当哲学家吃饭的时候,必须使用身边的两支筷子,此时两边的人就无法吃饭。将吃饭的过程打印出来。
     * */
    public static void main(String[] args) throws InterruptedException {
        /*五支筷子*/
        Chopstick c_a = new Chopstick("a");
        Chopstick c_b = new Chopstick("b");
        Chopstick c_c = new Chopstick("c");
        Chopstick c_d = new Chopstick("d");
        Chopstick c_e = new Chopstick("e");
        /*五个哲学家*/
        Philosopher t1 = new Philosopher("苏格拉底", c_a, c_b);
        Philosopher t2 = new Philosopher("柏拉图", c_b, c_c);
        Philosopher t3 = new Philosopher("亚里士多德", c_c, c_d);
        Philosopher t4 = new Philosopher("赫拉克利特", c_d, c_e);
        Philosopher t5 = new Philosopher("阿基米德", c_e, c_a);
        t1.start();
        Thread.sleep(30);//为了避免都拿起左边筷子而太快死锁
        t2.start();
        Thread.sleep(100);//为了避免都拿起左边筷子而太快死锁
        t3.start();
        Thread.sleep(200);//为了避免都拿起左边筷子而太快死锁
        t4.start();
        Thread.sleep(300);//为了避免都拿起左边筷子而太快死锁
        t5.start();
        //执行结果,最终会死锁,5个人都是拿起了左边的筷子,而右边的筷子在其他人手里
        //这种线程没有按预期结束,执行不下去的情况,归类为【活跃性】问题,除了死锁以外,还有活锁和饥饿者两种情况
    }
}

class Chopstick {
    private String name;

    public Chopstick(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Chopstick{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Philosopher extends Thread {
    private static Logger log = LoggerFactory.getLogger(Philosopher.class);
    private String name;
    private Chopstick leftChostick;
    private Chopstick rightChostick;

    public Philosopher(String name, Chopstick leftChostick, Chopstick rightChostick) {
        super(name);
        this.name = name;
        this.leftChostick = leftChostick;
        this.rightChostick = rightChostick;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (leftChostick) {
                log.info("{} 拿起左边筷子:{}", name, leftChostick.getName());
                synchronized (rightChostick) {
                    log.info("{} 拿起右边筷子:{}", name, rightChostick.getName());
                    eat();
                }
            }
        }
    }

    public void eat() {
        log.info("{} eat....", name);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return "Philosopher{" +
                "name='" + name + '\'' +
                ", leftChostick=" + leftChostick +
                ", rightChostick=" + rightChostick +
                '}';
    }
}

`

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不再让梦枯萎 2022-09-19 03:10:30
  • 尝试拿右边筷子时,如果等待超过一定时间仍然未能获取,则释放左边筷子的锁。
  • 使用公平锁避免右边的人已经在等筷子的情况下,自己刚放下右筷又拿起来,导致右边的人吃不到。

class Chopstick extends ReentrantLock{
    private String name;

    public Chopstick(String name) {
        super(true);
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Chopstick{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Philosopher extends Thread {
    private static Logger log = LoggerFactory.getLogger(Philosopher.class);
    private String name;
    private Chopstick leftChostick;
    private Chopstick rightChostick;
    private int times = 0;//吃了几次,

    public Philosopher(String name, Chopstick leftChostick, Chopstick rightChostick) {
        super(name);
        this.name = name;
        this.leftChostick = leftChostick;
        this.rightChostick = rightChostick;
    }

    @Override
    public void run() {
        while (!interrupted()) {
            leftChostick.lock();
            log.info("{} 拿起左边筷子:{}", name, leftChostick.getName());
            try {
                boolean acquired = rightChostick.tryLock(100, TimeUnit.MILLISECONDS);
                if (acquired) {
                    log.info("{} 拿起右边筷子:{}", name, rightChostick.getName());
                    eat();
                    rightChostick.unlock();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                leftChostick.unlock();
            }
        }
    }

    public void eat() {
        ++times;
        log.info("{} eat....,{}", name, times);
    }

    @Override
    public String toString() {
        return "Philosopher{" +
                "name='" + name + '\'' +
                ", leftChostick=" + leftChostick +
                ", rightChostick=" + rightChostick +
                '}';
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文