Java实现哲学家就餐问题

原创 2015年11月19日 21:03:57

什么是哲学家就餐问题?

我给出一种方法的实现

Chandy/Misra解法

1984年,K. Mani Chandy和J. Misra提出了哲学家就餐问题的另一个解法,允许任意的用户(编号P1, …,
Pn)争用任意数量的资源。与资源分级解法不同的是,这里编号可以是任意的。

  • 把筷子凑成对,让要吃的人先吃,没筷子的人得到一张换筷子券。
  • 饿了,把换筷子券交给有筷子的人,有筷子的人吃饱了会把筷子交给给券的人。有了券的人不会再得到第二张券。 保证有筷子的都有得吃。
  • 这个解法允许很大的并行性,适用于任意大的问题。

Java代码

  • Util.java
package com.coderbean.test;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Chang on 15/11/19.
 */
public class Util {
    int num = 0;
    List<Philosopher> philosopherList;  //store philosophers

    public Util() {
        philosopherList = new ArrayList<>();
//        philosopherList = new ArrayList<Philosopher>();
    }

    public Util(int num) {
        this();
        this.num = num;
    }

    public synchronized boolean getForks() {
        if(num>2) {
            num -= 2;
            return true;
        } else {
            return false;
        }
    }

    public synchronized void findBoss(Philosopher phi) {
        for(Philosopher p:philosopherList) {
            if(phi==p)
                continue;
            if(p.hasForks()&&!p.hasTicket()) {
                p.setPhilosopher(phi);
                p.setHasTicket(true);
                System.out.println(phi.getName()+"'s Boss is " +p.getName());
                phi.setHasTicket(false);
                System.out.println(""+phi.hasForks()+"餐具-"+phi.getName());
                phi.setHasForks(false);
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public synchronized void freeForks(Philosopher philosopher) {
        philosopher.getPhilosopher().setHasForks(true);
        System.out.println(""+philosopher.getName()+"给了"+philosopher.getPhilosopher().getName()+"餐具");
        philosopher.setHasForks(false);
        notifyAll();
    }
    public synchronized void debug() {
        System.out.println("\n" + philosopherList.size());
        for (Philosopher p : philosopherList) {
            System.out.println(p.hasForks() + "-" + p.hasTicket() + "\n");
        }
    }
}
  • Philosopher.java
package com.coderbean.test;

/**
 * Created by Chang on 15/11/19.
 */
public class Philosopher implements Runnable {
    private Util util;
    private String name;
    private boolean hasTicket;
    private boolean hasForks;
    private Philosopher philosopher;


    public Philosopher() {
        name = null;
        util = new Util();
        hasTicket = false;
        hasForks = false;
    }

    public Philosopher getPhilosopher() {
        return philosopher;
    }

    public String getName() {
        return name;
    }

    public void setPhilosopher(Philosopher philosopher) {
        this.philosopher = philosopher;
    }

    public boolean hasTicket() {
        return hasTicket;
    }

    public void setHasForks(boolean hasForks) {
        this.hasForks = hasForks;
    }

    public boolean hasForks() {
        return hasForks;
    }

    public void setHasTicket(boolean hasTicket) {
        this.hasTicket = hasTicket;
    }

    /**
     * 构造方法
     * @param util 筷子管理程序
     * @param name 哲学家名字
     */
    public Philosopher(Util util, String name) {
        this();
        this.util = util;
        this.name = name;
    }



    public void think(){
        System.out.println("I am Thinking----"+this.name);
        try {
            Thread.sleep(1000);  //模拟思考耗时
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void eat() {
        System.out.println("----------------------------I am Eating--"+this.name);
        try {
            Thread.sleep(500); //模拟吃饭耗时
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void run() {
        philosopher = new Philosopher();
        this.util.philosopherList.add(this); //take self to the list in Util
        this.hasForks = util.getForks();
        this.hasTicket = !this.hasForks;

        while (true) {
            this.think();

            if (this.hasForks) { // if has forks ,eat
                eat();
                if (this.hasTicket) { //有票有筷子 if has ticket, give forks to the ticket owner
                    util.freeForks(this);
                }//有筷子没票 什么都不干

            } else if (this.hasTicket) { //有票没筷子,找有筷子的人,给他票
                util.findBoss(this);
            }// 没筷子没票,什么都不敢
//            util.debug();
        }
    }
}
  • Main.java
package com.coderbean.test;

/**
 * Created by Chang on 15/11/19.
 */
public class Main {
    public static void main(String[] args) {
        Util util = new Util(5);
        new Thread(new Philosopher(util,"1")).start();
        new Thread(new Philosopher(util,"2")).start();
        new Thread(new Philosopher(util,"3")).start();
        new Thread(new Philosopher(util,"4")).start();
        new Thread(new Philosopher(util,"5")).start();
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

java多线程--哲学家就餐问题

java死锁,哲学家就餐问题
  • qq1004642027
  • qq1004642027
  • 2015年11月26日 14:53
  • 2739

尝试解决哲学家进餐问题(Java实现)

一. 问题描述 5个哲学家,5跟筷子,哲学家必须用两只筷子吃东西。他们只能使用自己左右手边的那两只筷子。做到不产生死锁以及要求高并发性。 二.  资源加锁法 直接给所请求...
  • stephenluu
  • stephenluu
  • 2014年03月18日 17:53
  • 5554

哲学家就餐问题(java实现)

1、问题描述(死锁) 五个哲学家,五只筷子,只有获得一双筷子之后才能就餐,就有可能出现这种情况:每个哲学家都获得了一只筷子,卡死在那个地方。 2、解决哲学家就餐问题当然后很多方...
  • leozston
  • leozston
  • 2016年12月05日 01:34
  • 726

java 多线程实现 哲学家进餐问题

每个哲学家面前都有一碟通心面,由于面条很滑所以要两把叉子才能夹住。相邻两个碟子之间有一把叉子。哲学家两种活动:即吃饭和思考。当一个哲学家觉得饿时他就试图去取他左边和右边的叉子。如果成功地获得两把叉子,...
  • tiantangpw
  • tiantangpw
  • 2016年02月13日 19:10
  • 532

java多线程哲学家思考吃饭问题

package test; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.ut...
  • kangaroo835127729
  • kangaroo835127729
  • 2015年03月05日 00:03
  • 1179

【操作系统】“哲学家进餐”问题

“哲学家进餐”问题有五个哲学家,他们的生活方式是交替地进行思考和进餐。他们共用一张圆桌,分别坐在五张椅子上。在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左、右最靠近他的筷子,...
  • qq_28602957
  • qq_28602957
  • 2016年12月09日 14:15
  • 2846

多线程处理哲学家就餐问题(GUI动态演示)

利用Java的多线程机制,以GUI形式动态演示解决哲学家就餐问题。
  • littleschemer
  • littleschemer
  • 2015年08月30日 18:39
  • 4449

哲学家就餐问题(java实现)

1、问题描述(死锁) 五个哲学家,五只筷子,只有获得一双筷子之后才能就餐,就有可能出现这种情况:每个哲学家都获得了一只筷子,卡死在那个地方。 2、解决哲学家就餐问题当然后很多方...
  • leozston
  • leozston
  • 2016年12月05日 01:34
  • 726

多线程--哲学家就餐问题

当哲学家的左右筷子均是可用的时候才能就餐,否则等待,很容易理解,一次最多能有两个人同时就餐...
  • havedream_one
  • havedream_one
  • 2015年07月05日 20:06
  • 794

java多线程--哲学家就餐问题

java死锁,哲学家就餐问题
  • qq1004642027
  • qq1004642027
  • 2015年11月26日 14:53
  • 2739
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java实现哲学家就餐问题
举报原因:
原因补充:

(最多只允许输入30个字)