用餐哲学家线程和信号量

时间:2013-01-13 13:47:13

标签: java multithreading semaphore dining-philosopher

我制作了一个简单的GUI,它有5个表格和分叉,并试图可视化这个着名的问题,但我无法实现完全实现。我没有得到我的代码卡住点,如果有人建议我解决这个问题,任何帮助将不胜感激,并提前感谢! 额外注意:还有一个错误,我猜它是关于我的数组创建想法,我有一个错误,如java.lang.ArrayIndexOutOfBoundsException:5。

public class Philosopher implements Runnable {


    private static Table table;
    private int ID;
    private int N = 5;
    private static Semaphore s1 = new Semaphore(1) ;
    private static Semaphore[] sarray = new Semaphore[5];
    private int[] array = new int[5];
    private int thinking = 0;
    private int hungry = 1;
    private int eating = 2;
    private int left = (ID + N - 1) % N;
    private int right = (ID + 1) % N;

    void test(int i)
    {
        if((array[i] == hungry) && (array[left] != eating) && (array[right] != eating))
        {
            table.ForkTake_GUI(i);
            array[i] = eating;
            sarray[i].release();

        }   
    }

    void take_forks(int i)
    {
        try {
            s1.acquire();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        array[i] = hungry;
        table.Hungry_GUI(i);
        test(i);
        s1.release();
        table.Eating_GUI(i);
        sarray[i].release();
    }

    void put_forks(int i)
    {
        table.StopEating_GUI(i);
        try {
            s1.acquire();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        array[i] = thinking;
        test(left);
        test(right);
        table.ForkPut_GUI(i);
        s1.release();

    }

    public Philosopher(int i)
    {
        setID(i);
    }

    public void run()
    {
        while(true)
        {
            Random RandomGenerator = new Random();
            int randomNum = RandomGenerator.nextInt(10);
            try {
                Thread.sleep((randomNum * 1000));
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            take_forks(ID);
            //table.Eating_GUI();
            put_forks(ID);      
        }

    }

    public static void main(String args[]) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    table = new Table();
                    table.frame.setVisible(true);
                }
                catch(Exception e){
                    e.printStackTrace();
                }

            }
        });

        Philosopher p1 = new Philosopher(1);
        Philosopher p2 = new Philosopher(2);
        Philosopher p3 = new Philosopher(3);
        Philosopher p4 = new Philosopher(4);
        Philosopher p5 = new Philosopher(5);
        Thread pt1 = new Thread(p1);
        Thread pt2 = new Thread(p2);
        Thread pt3 = new Thread(p3);
        Thread pt4 = new Thread(p4);
        Thread pt5 = new Thread(p5);

        sarray[0] = new Semaphore(1);
        sarray[1] = new Semaphore(1);
        sarray[2] = new Semaphore(1);
        sarray[3] = new Semaphore(1);
        sarray[4] = new Semaphore(1);

        pt1.start();
        pt2.start();
        pt3.start();
        pt4.start();
        pt5.start();

    }
    public int getID() {
        return ID;
    }
    public void setID(int iD) {
        ID = iD;
    }

}

1 个答案:

答案 0 :(得分:1)

看一下从sarray获取互斥锁的位置 - 重点是你没有,所以至少那里有多余的代码。

补充说明:

  • 你定义N但是全部使用幻数5。
  • 您似乎有一个“中央”互斥锁,每个叉子一个。使用中央互斥锁已经解决了原始问题。
  • 考虑将每个互斥锁及其保护的数据放入聚合中。这样可以清楚地表明,五个互斥体是针对五个分支而不是五个哲学家,或者?
  • 你的出界显然是由1基数和0基指数之间的转换引起的。可能是因为左右计算后更改ID会导致这种情况吗?一般来说,我不会将这些存储为成员。另外,要注意你所拥有的价值观是为了哲学家,而不是为了福音!画一幅画,这将有助于你做到这些!