欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

哲学家问题

程序员文章站 2022-07-04 23:34:50
...

描述:五个哲学家围着一张圆桌,每个哲学家面前放着食物。哲学家的生活有两种交替活动:吃饭思考。当一个哲学家吃饭时,需要先拿起自己左右两边的两根筷子,并且一次只能拿起一根筷子。

解决1:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。设置一个信号量room,使其初始值为4,在哲学家拿起他左边的筷子之前,先对信号量做一次P操作,从而当第五位哲学家去拿做筷子时,room = -1被阻塞,避免了死锁问题。然后当哲学家放下他左边的筷子的时候,就对r做一次V操作。

semaphore chopstick[5]={1,1,1,1,1};
semaphore count=4; // 设置一个count,最多有四个哲学家可以进来
void philosopher(int i)
{
	while(true)
	{
		think();
		wait(count); //请求进入房间进餐 当count为0时 不能允许哲学家再进来了
		wait(chopstick[i]); //请求左手边的筷子
		wait(chopstick[(i+1)%5]); //请求右手边的筷子
		eat();
		signal(chopstick[i]); //释放左手边的筷子
		signal(chopstick[(i+1)%5]); //释放右手边的筷子
		signal(count); //退出房间释放信号量
	}
}

解决2:仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐

public class ThreadTest{
    public static void main(String[] args) {
        Fork fork = new Fork();
        new Philosopher("0",  fork).start();
        new Philosopher("1",  fork).start();
        new Philosopher("2",  fork).start();
        new Philosopher("3",  fork).start();
        new Philosopher("4",  fork).start();
    }
}

class Philosopher extends Thread{
    private String name;
    private Fork fork;

    public Philosopher(String name, Fork fork) {
           super(name);
           this.name = name;
           this.fork = fork;
    }

    @Override
    public void run() {
        while (true){
            thinking();
            fork.takeFork();
            eating();
            fork.putFork();
        }
    }

    public void eating(){
        System.out.println("I am Eating:"+name);
        try {
              sleep(1000);//模拟吃饭,占用一段时间资源
        } catch (InterruptedException e) {
              e.printStackTrace();
        }
    }


    public void thinking(){
        System.out.println("I am Thinking:"+name);
        try {
                sleep(1000);//模拟思考
        } catch (InterruptedException e) {
                e.printStackTrace();
        }
    }


    public Fork getFork() {
           return fork;
    }

    public void setFork(Fork fork) {
           this.fork = fork;
    }
}

class Fork{
       /*5只筷子,初始为都未被用*/
        private boolean[] used={false,false,false,false,false,false};
        public synchronized void takeFork(){
        	String name = Thread.currentThread().getName();
        	int i = Integer.parseInt(name);
        	while(used[i] || used[(i+1)%5]){
            		try {
                		wait();//如果左右手有一只正被使用,等待
            		} catch (InterruptedException e) {
                		e.printStackTrace();
           	 	}
       	 	}
       	 	used[i ]= true;
        	used[(i+1)%5]=true;
    	}

      public synchronized void putFork(){
        	String name = Thread.currentThread().getName();
        	int i = Integer.parseInt(name);
        	used[i]= false;
        	used[(i+1)%5]=false;
        	notifyAll();//唤醒其他线程
        }
}
相关标签: java 多线程