餐饮哲学家,但十个哲学家.我想更改此解决方案.我想完成这段代码. [英] Dining Philosophers but ten Philosophers. I want to change this solution. I want to complete this code.

查看:90
本文介绍了餐饮哲学家,但十个哲学家.我想更改此解决方案.我想完成这段代码.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

10位哲学家进行至少5次饮食和思考交易,并使他们变得充实.(使用Java)



10 philosophers eating and thinking transaction at least 5 times and make them to be full.(with java)



package diningphilosophers;



public class DiningPhilosophers {

    public static void main(String[] args) {
        
        Table table = new Table();
        
        for(int i = 0; i < <strong class="highlight">10</strong>; i++) {
            Philosopher newGuy = new Philosopher(i);
            table.sitAt(newGuy);
            Thread starter = new Thread(newGuy);
            starter.start();            
        }
    }
}---------------------------------------
package diningphilosophers;


public class Fork {
    Philosopher heldBy;
    
    public Fork grabFork(Philosopher grabber) {
        if(heldBy == null) {
            heldBy = grabber;
            return this;
        }
        return null;
    }
    
    public boolean releaseFork(Philosopher releaser) {
        if(heldBy.equals(releaser)) {
            heldBy = null;
            return true;
        }
        return false;
    }
    
    public boolean isAvailable() {
        if(heldBy == null) {
            return true;
        }
        
        return false;
    }
}--------------------------------------------------------------
package diningphilosophers;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Philosopher implements Runnable{

    private Fork leftFork, rightFork;
    private Table atTable;
    private int tablePosition;
    private boolean isFull;
    private Random randomGenerator = new Random();
    
    public Philosopher(int tablePosition) {
        this.tablePosition = tablePosition;
        leftFork = null;
        rightFork = null;
        isFull = false;
    }
    
    
    @Override
    public void run() {
        for(int i = 0; i < <strong class="highlight">5</strong>; i++) {
            <strong class="highlight">think</strong>();
            <strong class="highlight">eat</strong>();
        }
        isFull = true;
        System.out.println("Philosopher " + tablePosition + " is done!");
    }
    
    private void <strong class="highlight">think</strong>() {        
        System.out.println("Philosopher " + tablePosition + " is thinking...");
        try {
            Thread.sleep(randomGenerator.nextInt(500));
        } catch (InterruptedException ex) {
            Logger.getLogger(Philosopher.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void setTable(Table table) {
        atTable = table;
    }
    
    private void <strong class="highlight">eat</strong>() {
        getLeftFork();
        System.out.println("Philosopher " + tablePosition + " got his left fork!");
        getRightFork();
        System.out.println("Philosopher " + tablePosition + " got his right fork!");
        System.out.println("Philosopher " + tablePosition + " is eating...");
        
        try {
            Thread.sleep(randomGenerator.nextInt(500));
        } catch (InterruptedException ex) {
            Logger.getLogger(Philosopher.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        releaseForks();
    }
    
    private void getLeftFork() {
        while (true) {
            leftFork = atTable.getLeftFork(tablePosition);
            if(leftFork != null) {
                return;
            }
            else {
                try {
                    Thread.sleep(randomGenerator.nextInt(100));
                } catch (InterruptedException ex) {
                    Logger.getLogger(Table.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    
    private void getRightFork() {
        while (true) {
            rightFork = atTable.getLeftFork(tablePosition);
            if(rightFork != null) {
                return;
            }
            else {
                try {
                    Thread.sleep(randomGenerator.nextInt(100));
                } catch (InterruptedException ex) {
                    Logger.getLogger(Table.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    
    private void releaseForks() {
        leftFork = null;
        rightFork = null;
        atTable.releaseForks(tablePosition);
    }
    
    public int tablePosition() {
        return tablePosition;
    }        
    
}---------------------------------------------------------
/*
 * To change this template, choose Tools | Templates
 * <strong class="highlight">and</strong> open the template in the editor.
 */
package diningphilosophers;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 *
 *
 */
public class Table {
    
    private Fork[] forks = new Fork[10];
    private Philosopher[] <strong class="highlight">philosophers</strong> = new Philosopher[10];
    
    public Table() {
        for(int i = 0; i < forks.length; i++) {
            forks[i] = new Fork();
            <strong class="highlight">philosophers</strong>[i] = null;
        }
    }
    
    public boolean sitAt(Philosopher eater) {
        int index = eater.tablePosition();
        if(index >= 0 && index < <strong class="highlight">philosophers</strong>.length) {
            <strong class="highlight">philosophers</strong>[index] = eater;
            eater.setTable(this);
            return true;
        }
        return false;
    }
    
    public Fork getLeftFork(int index) {
        if (index < 0 && index >= forks.length) {
            System.out.println("Something went wrong...");
            System.exit(1);
        }        
        return forks[index].grabFork(<strong class="highlight">philosophers</strong>[index]);
    }
    
    public Fork getRightFork(int index) {
        if (index < 0 && index >= forks.length) {
            System.out.println("Something went wrong...");
            System.exit(1);
        }
        return forks[(index + 1)%forks.length].grabFork(<strong class="highlight">philosophers</strong>[index]);    
    }
    
    public void releaseForks(int index) {
        forks[index].releaseFork(<strong class="highlight">philosophers</strong>[index]);
        forks[(index+1)%forks.length].releaseFork(<strong class="highlight">philosophers</strong>[index]);
    }
    
}




代码块移动到代码周围-OriginalGriff [/edit]




[edit]Code block move to around the code - OriginalGriff[/edit]

推荐答案

好,我看了一下代码. 从任何意义上讲,这都不是餐饮哲学家的问题!

您甚至都没有试图解决这个问题.问题与线程有关,但是您永远不会创建单个线程.每个哲学家都应该是一个单独的线程,问题的要求也禁止使哲学家与众不同,例如,使逻辑的任何部分依赖于诸如哲学家ID之类的东西.每个fork应该是一个线程或某个线程同步原语.哲学家和叉子之间可以有许多不同的协作实现方式.我有一个使用套接字,EventWaitHandle等的变体.

您不能不使用线程同步原语来进行资源分配(作为资源的派生),而只能使用所有的"ifs"和"switched".原则上不可能正确执行.

叉子的数量与哲学家的数量相同,并且它们之间被放置.哲学家首先向右走(永远是某人的左边),然后再向左走(总是某人的右边),进餐,以相同的顺序放回叉子,然后出去,然后重复循环.僵局发生在每个哲学家拿起右叉并等待左叉的时候.您应该演示一下.

由于这都是难以检测的线程死锁,因此如果没有线程,该问题将毫无意义.在我看来,您只是模仿尝试解决此问题,而实际上甚至没有尝试.我不想提供任何进一步的帮助.您需要转储所有代码并首先阅读该理论.这个问题并不难实现,但是您应该真正熟悉线程和同步.



为了让您对餐饮哲学家问题的实现有一个了解,请看一下这篇文章.
现有代码中的死锁检测 [
—SA
OK, I took a look at the code. This is not a dining philosophers problem in any sense at all!

You''re not even trying to address the issue. The problem is about threads, but you never create a single thread. Each philosopher should be a separate thread, also the requirements of the problem prohibits to make philosophers different, say, make any part of logic depending, on, say philosopher ID or something like that. Each fork should be either a thread or some thread synchronization primitive. There can be many different implementation of collaboration between philosophers and forks. I had a variant using sockets, EventWaitHandle and more.

You cannot do resource allocation (a fork as a resource) not using thread synchronization primitives, just using all you "ifs" and "switched". It is not possible to do it correctly in principle.

The number of forks is the same as number of philosophers and they are placed between them. The philosopher take right on first (which is always someone''s left), than takes the left one (which is always someone''s right), eat, put forks back in the same order and goes out, then repeat the cycle. The deadlock happens when each philosopher took a right fork and waiting for the left one. You''re supposed to demonstrate it.

As this is all about a hard-to-detect thread deadlock, so the problem makes no sense without threads. In my opinion, you only imitate trying to solve this problem but in fact not even trying. I don''t want to provide any further help. You need to dump all you code and read the theory first. The problem is not hard to implement, but you should be really comfortable with threading and synchronization.



To get you an idea of the implementation of the dining philosophers problem, look at the article.
Deadlock Detection in Existing Code[^].

Please look at my comments to the article. I question if the method suggested by the author can detect the deadlock of the dining philosophers problem. The author maintained it can, but I proved it cannot.

You can find my very simple implementation in my comment entitled "No, dining philosophers did not get any help", please see.

—SA


这篇关于餐饮哲学家,但十个哲学家.我想更改此解决方案.我想完成这段代码.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆