-1

我制作了一个包含 5 个表和叉子的简单 GUI,并试图可视化这个著名的问题,但我无法完全实现。我没有得到我的代码的卡点,如果有人建议我解决这个问题,任何帮助将不胜感激并提前感谢!额外说明:还有一个错误,我猜这与我的数组创建想法有关,我有一个错误为 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;
    }

}
4

1 回答 1

1

看看你从哪里获得互斥锁sarray- 关键是你没有,所以至少那里有冗余代码。

进一步说明:

  • 您定义了 N,但全部使用了幻数 5。
  • 您似乎有一个“中央”互斥锁,每个分叉都有一个。使用中央互斥体已经解决了最初的问题。
  • 考虑将每个互斥体及其保护的数据放入一个聚合中。这将清楚地表明,五个互斥锁是针对五个分叉的,而不是针对五个哲学家的,或者?
  • 您的越界显然是由 1-base 和 0-based 索引之间的转换引起的。会不会是左右计算后改变ID造成的?一般来说,我不会将这些存储为成员。另外,请注意,您拥有的价值观是针对哲学家的,而不是针对叉子的!画一幅画,这将帮助你做对!
于 2013-01-14T06:47:20.820 回答