栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程解决哲学家就餐问题(Java)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程解决哲学家就餐问题(Java)

多线程解决哲学家就餐问题(Java)

       哲学家就餐问题是计算机科学中的一个经典问题,用于演示在并行计算中多线程同步时产生的问题。
题目要求:
        五位哲学家围着一张桌子而坐,他们不交谈,每人面前放了一碗饭,每个人之间放了一只筷子(总共5只筷子)。哲学家只能做两件事, 吃饭和思考,吃饭时不思考,思考时不吃饭。哲学家只能拿起自己身边的两只筷子才能吃饭,拿筷子的顺序是先拿左手再拿右手(不同时)。

题目分析:
  因为哲学家之间不会交谈故可能会发生很严重的情况:
      1.发生死锁,即每个哲学家都是左手拿着筷子,等待着右侧的筷子空闲,这就发生了死锁,谁也吃不了饭。
       2.出现他们同时左手拿起筷子,又同时放下左手的筷子,循环往复。
       3.不加锁则会出现五个人同时吃饭的情况。

解题流程:
      首先判断左右手是否同时有空闲的筷子,如果没有,就持续思考,如果有,则先取左手筷子再取右手筷子,然后停止思考并吃饭,吃完饭后清洗筷子放到桌面上并继续思考,此时处于吃饱状态,不会再重复吃饭。

public class Test {

	public static void main(String[] args) {
		Object obj = new Object();
		boolean[] chopsticks= {false,false,false,false,false};//每位哲学家的筷子初始状态
		for (int i = 0; i<5; i++) {
			//创建线程
			Philosophy phi = new Philosophy(i, false, false, true, true);
			phi.setObj(obj);//带锁
			phi.setChopsticks(chopsticks);//传筷子
			phi.start();//启动线程
		}
	}

}

class Philosophy extends Thread{
	//筷子状态
	boolean[] chopsticks; //true 拿起    false  放下
	//哲学家编号
	private int i;
	//左手
	private Boolean leftFlag = false;//true 拿起    false  放下
	//右手
	private Boolean rightFlag = false;//true 拿起    false  放下
	//饥饿状态
	private Boolean hungry = true;//true 饥饿    false  已经吃完饭
	//思考状态
	private Boolean thinkFlag = false;//true 思考中    false 未思考

	private Object obj;//锁

	//有参构造
	public Philosophy(int i, Boolean leftFlag, Boolean rightFlag, Boolean hungry,
			Boolean thinkFlag) {
		this.i = i;
		this.leftFlag = leftFlag;
		this.rightFlag = rightFlag;
		this.hungry = hungry;
		this.thinkFlag = thinkFlag;
	}

	//吃饭
	public void eat() {
		synchronized (obj) {
			//当前哲学家的左右筷子都空闲  并且是饥饿状态  可以拿筷子
			if(!chopsticks[this.i]&&!chopsticks[(this.i+1)%5]&&
					!this.leftFlag&&!this.rightFlag&&this.hungry) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				chopsticks[(this.i+1)%5] = true; //筷子被拿起
				this.leftFlag=true;//左手有筷子
				System.out.println("哲学家"+this.i+"拿起了左边的筷子");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				chopsticks[this.i] = true; //筷子被拿起
				this.rightFlag=true;//右手有筷子
				System.out.println("哲学家"+this.i+"拿起了右边的筷子");
			}
		}
		if(this.leftFlag&&this.rightFlag&&this.hungry) {//满足条件  开始吃饭
			System.out.println("哲学家"+this.i+"开始吃饭");
			this.thinkFlag=false;//停止思考
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("哲学家"+this.i+"吃完饭了");
			this.hungry=false;//不饿
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("哲学家"+this.i+"洗净并放下了筷子");
			System.out.println("哲学家"+this.i+"开始思考");
			this.thinkFlag=true;//思考
			this.leftFlag=false;//左手放下筷子
			this.rightFlag=false;//右手放下筷子
			chopsticks[i] = false;
			chopsticks[(i+1)%5] = false;
		}
	}


	//思考
	public void think() {
		if(!this.leftFlag&&!this.rightFlag&&!this.thinkFlag) {
			thinkFlag = true;
			System.out.println("哲学家"+i+"开始思考");
		}
	}
	
	//线程方法
	@Override
	public void run() {
		while(true) {//循环判断每位哲学家的状态以及筷子的状态
			this.eat();
			this.think();
		}
	}
	
	//设置筷子状态
	public void setChopsticks(boolean[] chopsticks) {
		this.chopsticks = chopsticks;
	}
	
	//设置锁对象
	public void setObj(Object obj) {
		this.obj = obj;
	}
}

运行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/666238.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号