一、问题分析
二、概要设计
(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秒。
源码下载 : 点击打开链接