进程同步互斥——不死锁哲学家问题



一、问题分析



 

二、概要设计

(1)利用进程并发执行原理,采用奇数号哲学家先拿左叉子,偶数号哲学家先拿右叉子的算法解决哲学家就餐问题。

(2)利用java中Swing技术将哲学家就餐的活动过程用可视图形化界面表示出来


三、代码实现:

Philosopher类

  /**
   * Philosopher类模拟哲学家的就餐活动过程
   * @author Administrator
   */
  public class Philosopher extends JLabel implements Runnable{
  	/**
  	 * 哲学家编号
  	 */
  	private int id = 0;
  	
  	/**
  	 * suspend = true 线程暂停
  	 */
  	private boolean suspend = false;
  
  	public Philosopher(int id, Semaphore leftFork, Semaphore rightFork, 
  		//哲学家初始化设计,统一设计哲学家的初始状态为思考
  	}
  	
  	/**
  	 * 若suspend设置为false,继续运行当前进程
  	 */
  	public void setSuspend(boolean suspend) {
  		//使用Object的notifyAll()方法来唤醒当前线程
  	}
  	
  	/**
  	 * 状态转为思考
  	 */
  	private void think() {
  //返回信息给用户,并将当前图像设为思考的图像。
  	}
  	
  	/**
  	 * 状态转为就餐
  	 */
  	private void eat() {
  //返回信息给用户,并将当前图像设为思考的图像。
  	}
  	
  	/**
  	 * 申请右叉子
  	 */
  	private void waitRightFork(){
  		//使用Semaphore.acquire()向计数信号量获得一个许可,来模拟申请右			//叉子.
  //返回相关状态信息给用户
  	}
  	
  	/**
  	 * 申请左叉子
  	 */
  	private void waitLeftFork() throws InterruptedException {
  //使用Semaphore.acquire()向计数信号量获得一个许可,来模拟申请左	//叉子.
  //返回相关状态信息给用户
  	}
  	
  	/**
  	 * 释放所有叉子
  	 */
  	private void releaseFork() {
  //使用Semaphore.release() 释放一个许可,将其返回给信号量。来模	//拟释放左右叉子.
  //返回相关状态信息给用户
  	}
  	
  	/**
  	 * 判断是否要暂停当前进程
  	 */
  	private void checkSuspend() {
  		//Object的wait()方法来暂停当前线程
  	}
  	
  	/**
  	 * 奇数号哲学家先拿左叉子,偶数号哲学家先拿右叉子
  	 */
  	public void run() {
  		try{
  			while(true) {
  				//设状态为思考
  				if(id % 2 == 1) {
  					//奇数号哲学家先拿左叉子
  				}
  				else {
  					//偶数号哲学家先拿右叉子
  				}
  				//设状态为吃东西
  				//释放所有叉子
  			}
  		}
  	}
  	
  }

四、调试分析

(1)调试和设计过程中遇到的问题与解决

1) 问题:实现同步互斥时,只用了简单的线程同步方法,无法实现互斥

  解决方法:使用java中Semaphore类来创建信号量,并通过 Semaphore.acquire() 和Semaphore.release()来模拟叉子的释放和申请

2) 问题:本程序为方便用户观看哲学家们就餐的过程,在程序中添加了一个控制 按钮来控制程序的运行和暂停,但java中的Thread.stop()被认为线程不安全, 所以不能使用该方法来控制线程.

  解决方法:Object的wait()和notifyAll()方法。使用这两个方法让线程暂停,并且还能恢复,向哲学家类中添加一个标志变量suspend方法,每个状态发生改变时,检查标志变量suspend的值来决定是否要暂停当前线程,从而主程序可以通过改变哲学家类中的suspend的值,来控制是否暂停当前哲学家进程。

3) 问题:释放叉子和改变叉子的显示状态问题,如果先释放叉子,然后再改变叉子状态就会出现以下问题。

 


虽然叉子的信号量已被申请出去,但用户看到的却是叉子还存在的状态。

解决方法:先显示叉子,再释放叉子的信号量。

五、用户使用说明

本程序利用进程并发执行的原理,设计合适的算法来解决哲学家就餐问题,并把哲学家们的活动过程用文字和可视化图像显示出来。所以在程序中只用一个用来控制程序暂停和运行的可操作按钮。

 

 

六、测试与运行结果

本程序为模拟哲学家就餐的活动过程,如下图所示5位哲学家和5把叉子,哲学家们的初始状态都为“思考”,在程序界面中,顺时针方向为左,逆时针方向为右

 


每个哲学家有3个状态:“思考”,“饥饿”和“吃面”,每个哲学家进程通过信号量来实现同步互斥。为了方便用户观看,使用Tread.sleep()方法使“思考”和“吃面”状态至少进行3秒。

 

 


源码下载 : 点击打开链接


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值