操作系统中的哲学家进餐问题的实现(java实现)

在学习操作系统这本书的时候,我们使用的是汤小丹老师的《计算机操作系统》接下来我将会使用java语言去实现内部代码。

Swap指令

哲学家就餐问题是在计算机科学中的一个经典问题,用来演示在并行计算中多线程同步(Synchronization)时产生的问题。在1971年,著名的计算机科学家艾兹格·迪科斯彻提出了一个同步问题,即假设有五台计算机都试图访问五份共享的磁带驱动器。稍后,这个问题被托尼·霍尔重新表述为哲学家就餐问题。这个问题可以用来解释死锁和资源耗尽。

利用记录型信号量解决哲学家进餐问题,但是这样会这引起如结果所示的死锁问题。

package chapter02;

public class P69_1 {
    static int[] chopstick = {1,1,1,1,1};

    public static void main(String[] args) {
        InnerThread a0 = new InnerThread();
        a0.setName("0");
        a0.start();

        InnerThread a1 = new InnerThread();
        a1.setName("1");
        a1.start();

        InnerThread a2 = new InnerThread();
        a2.setName("2");
        a2.start();

        InnerThread a3 = new InnerThread();
        a3.setName("3");
        a3.start();

        InnerThread a4 = new InnerThread();
        a4.setName("4");
        a4.start();
    }

    static class InnerThread extends Thread{
        @Override
        public synchronized void run() {
            while (true){
                int index = Integer.parseInt(this.getName());
                if(chopstick[index]==1){
                    chopstick[index]=0;
                    System.out.println("哲学家"+this.getName()+"获得左筷子"+",筷子序号为"+index);
                }else{
                    //否则睡眠
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                if(chopstick[((index+1)%chopstick.length)]==1){
                    chopstick[((index+1)%chopstick.length)]=0;
                    System.out.println("哲学家"+this.getName()+"获得左筷子"+",筷子序号为"+(index+1)%chopstick.length);

                    System.out.println("哲学家"+this.getName()+"吃饭");
                    try {
                        Thread.sleep(1000);
                        //进行赋值
                        chopstick[index]=1;
                        chopstick[((index+1)%chopstick.length)]=1;
                        System.out.println("哲学家"+this.getName()+"思考");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    //否则睡眠
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

运行结果:

"C:\Program Files\Java\jdk1.8.0_101\bin\java.exe" 
哲学家0获得左筷子0序号为
哲学家3获得左筷子3序号为
哲学家1获得左筷子1序号为
哲学家2获得左筷子2序号为
哲学家4获得左筷子4序号为

Process finished with exit code -1

 

解决办法:

1.至多允许四位哲学家同时拿起筷子,最终能保证一位哲学家能够进食。

 

2.仅当左右筷子都可以使用的时候才允许拿起筷子

3.规定奇数哲学家先拿起左筷子,然后再拿右筷子,反之亦然。

好的,这里是操作系统哲学家进餐问题Java程序实现: ```java import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class DiningPhilosophers { private static final int NUMBER_OF_PHILOSOPHERS = 5; private static final int SIMULATION_TIME = 1000; public static void main(String[] args) throws InterruptedException { Philosopher[] philosophers = new Philosopher[NUMBER_OF_PHILOSOPHERS]; Object[] forks = new Object[NUMBER_OF_PHILOSOPHERS]; Lock[] locks = new Lock[NUMBER_OF_PHILOSOPHERS]; for (int i = 0; i < NUMBER_OF_PHILOSOPHERS; i++) { forks[i] = new Object(); locks[i] = new ReentrantLock(); } for (int i = 0; i < NUMBER_OF_PHILOSOPHERS; i++) { philosophers[i] = new Philosopher(i, forks[i], forks[(i + 1) % NUMBER_OF_PHILOSOPHERS], locks[i], locks[(i + 1) % NUMBER_OF_PHILOSOPHERS]); new Thread(philosophers[i]).start(); } Thread.sleep(SIMULATION_TIME); for (Philosopher philosopher : philosophers) { philosopher.setFull(true); } } } class Philosopher implements Runnable { private final int id; private final Object leftFork; private final Object rightFork; private final Lock leftLock; private final Lock rightLock; private volatile boolean isFull = false; public Philosopher(int id, Object leftFork, Object rightFork, Lock leftLock, Lock rightLock) { this.id = id; this.leftFork = leftFork; this.rightFork = rightFork; this.leftLock = leftLock; this.rightLock = rightLock; } @Override public void run() { try { while (!isFull) { think(); pickUpForks(); eat(); putDownForks(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } private void think() throws InterruptedException { System.out.println("Philosopher " + id + " is thinking"); Thread.sleep((long) (Math.random() * 10000)); } private void pickUpForks() throws InterruptedException { leftLock.lock(); try { System.out.println("Philosopher " + id + " picked up left fork"); rightLock.lock(); try { System.out.println("Philosopher " + id + " picked up right fork"); } catch (Exception e) { leftLock.unlock(); throw e; } } catch (Exception e) { rightLock.unlock(); throw e; } } private void eat() throws InterruptedException { System.out.println("Philosopher " + id + " is eating"); Thread.sleep((long) (Math.random() * 10000)); } private void putDownForks() { leftLock.unlock(); rightLock.unlock(); System.out.println("Philosopher " + id + " put down forks"); } public void setFull(boolean isFull) { this.isFull = isFull; } } ``` 这个程序,有5个哲学家和5个餐叉,每个哲学家需要同时拿到左右两边的餐叉才能进餐,否则需要等待。使用 `Lock` 和 `ReentrantLock` 来实现锁定餐叉。程序的运行时间为1000毫秒,每个哲学家会先思考一段时间,然后尝试拿起餐叉,进餐,然后放下餐叉,最后再开始思考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值