心情bert

永不言弃..

逝者如斯
网志分类
· 所有网志 (21)
搜索本站
友情链接
· 我的歪酷 非非共享界
· 俺家思雨
· 小黄
·

订阅 RSS

0006316

歪酷博客


« 上一篇: 恒心... 下一篇: 最近的笔面试 »
bert @ 2008-08-31 16:26

刚看过java线程,于是尝试着模拟一下经典的哲学家就餐问题。
总是看别人的还是不行,自己动手,收获要多一些。

下面这个最终结果,修改过几次。
比如关于wait()调用,开始没注意到调用它会释放
监视器,然后发现了。又想查一下jdk文档确认,诧异地发现没有释放监视器的说明。再仔细看一遍,原来是中文版把release错误地翻译成了发布...应该是释放
还有是死锁:开始的版本会发生5个人都拿起了左手的叉子...
后来改成如果拿右边叉子失败,释放左手的,不断重试
sleep函数也很重要,否则虽然运行正确,结果却很怪异

class Fork
{
    private boolean lockon;
    public Fork(){ lockon = false; }
    public boolean isLocked()
    {
        return lockon == true;
    }
    public synchronized void Lock()
    {
        while (lockon == true)
        {
            try
            {
                wait();
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        lockon = true;
    }
    public synchronized void unLock()
    {
        lockon = false;
        notifyAll();
    }
}

class Philo extends Thread
{
    private char name; //哲学家的名字:A B C D E
    private static Fork[] forks = new Fork[5];//共用5根叉子
    private Fork left;
    private Fork right;
    static
    {
        for (int i=0; i<5; i++)
        {
            forks[i] = new Fork();
        }
    }
    public Philo(int i)
    {
        left  = forks[i];
        right = forks[(i+1)%5];
    }
    public void setMyName (char name)
    {
        this.name = name;
    }
    public char getMyName ()
    {
        return this.name;
    }
    public void getLeftFork()
    {
        left.Lock();
    }
    public boolean getRightFork() //确保拿了左筷子才拿右筷子,右不可拿则释放左筷子
    {
        if ( right.isLocked()) //破坏死锁四大条件之一:占有且等待
        {
            left.unLock();
            System.out.println(getMyName()+" put left fork");
            return false;
        }
        else
        {
            right.Lock();
            return true;
        }
    }
    public void putLeftFork()
    {
        left.unLock();
    }
    public void putRightFork()
    {
        right.unLock();
    }
   
    public void run()
    {
        while(true)
        {

            boolean succ = false;

            System.out.println(getMyName()+" is thinking");
            while (succ != true)
            {
                getLeftFork();
                System.out.println(getMyName()+" get left fork");
                if(getRightFork())
                {
                    succ = true;
                    System.out.println(getMyName()+" get right fork");
                }
                try{
                    Thread.sleep((long)(Math.random()*1000));
                    }catch (InterruptedException e) {
                    e.printStackTrace();
                    }
            }
            System.out.println(getMyName()+" is eating");
            try{
                Thread.sleep((long)(Math.random()*2000));
                }catch (InterruptedException e) {
                e.printStackTrace();
                }
            putRightFork();
            putLeftFork();
            System.out.println(getMyName()+" eaten done!");
        }       
    }
}
   
public class runPhilo
{
    public static void main( String[] args )
    {
        Philo[] philosopher = new Philo[5];
        char ch = 'A';
        for ( int i=0; i<5; i++)
        {
            philosopher[i] = new Philo(i);
            philosopher[i].setMyName(ch++);
        }
        for (int i=0; i<5; i++)
        {
            philosopher[i].start();
        }
        System.out.println("Main thread is running");
    }
}




评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定