哲学家就餐问题是指5个哲学家坐成一圈,每两个之间有一把叉子,只有当同时握有两把叉子才能用餐,哲学家除了吃饭还有思考时间,假如5个哲学家同时拿起左手的叉子,这时候又准备拿右手的叉子,那么将陷入死锁状态;假如规定如果左手叉子拿到之后一段时间没拿到右手叉子,那么将放下左手叉子,然后再继续尝试,那么这样就有可能陷入死循环的状态。本文主要通过给定叉子的状态,每次取叉子需要判断左右两边的叉子是否未被使用,如果是的则取叉子,如果任意其中一个被使用了,则等待;同时用完叉子之后,需要将叉子放下;为避免线程安全问题,对取叉子和放叉子加锁。代码如下:
import java.util.*;
public class PhilosopherProblem {
class Philosopher extends Thread{
private String name;
private Fork fork;
public Philosopher(String name,Fork fork){
super(name);
this.name=name;
this.fork=fork;
}
public void run() {
while(true)
{
fork.take();
eating();
fork.put();
thinking();
}
}
public void eating()
{
System.out.println("Philosopher"+name+" says:"+"I am eating now!");
try {
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
public void thinking()
{
System.out.println("Philosopher"+name+" says:"+"I am full and want to think for some time!");
try {
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
class Fork {
private boolean state[];
private int n;
public Fork(int n)
{
this.state=new boolean[n];
this.n=n;
}
//为了保证线程同步,take和put两个动作都用synchronized修饰,防止相邻两个人同取一个筷子的情况
public synchronized void take() {
String name = Thread.currentThread().getName();
int i = Integer.parseInt(name);
while(state[i]||state[(i+1)%n]){
try {
wait();//如果左右手有一只正被使用,等待
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//当左右两边筷子都未被使用,则拿起两边的筷子
System.out.println("Philosopher"+i+"get two forks and is ready to eat!");
state[i]= true;
state[(i+1)%n]=true;
}
public synchronized void put() {
String name = Thread.currentThread().getName();
int i = Integer.parseInt(name);
//使用完之后放下筷子
System.out.println("Philosopher"+i+"put two forks and is ready to think!");
state[i]= false;
state[(i+1)%n]=false;
notifyAll();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Please write the number of philosopher: ");
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
PhilosopherProblem pp=new PhilosopherProblem();
Fork fork=pp.new Fork(n);
for(int i=0;i<n;i++)
{
pp.new Philosopher(""+i,fork).start();
}
}
}
运行结果如下:
Please write the number of philosopher:
5
Philosopher0get two forks and is ready to eat!
Philosopher2get two forks and is ready to eat!
Philosopher2 says:I am eating now!
Philosopher0 says:I am eating now!
Philosopher0put two forks and is ready to think!
Philosopher0 says:I am full and want to think for some time!
Philosopher4get two forks and is ready to eat!
Philosopher4 says:I am eating now!
Philosopher2put two forks and is ready to think!
Philosopher2 says:I am full and want to think for some time!
Philosopher1get two forks and is ready to eat!
Philosopher1 says:I am eating now!
Philosopher1put two forks and is ready to think!
Philosopher1 says:I am full and want to think for some time!
Philosopher2get two forks and is ready to eat!
Philosopher2 says:I am eating now!
Philosopher4put two forks and is ready to think!
Philosopher4 says:I am full and want to think for some time!
Philosopher0get two forks and is ready to eat!
Philosopher0 says:I am eating now!
Philosopher2put two forks and is ready to think!
Philosopher2 says:I am full and want to think for some time!
Philosopher3get two forks and is ready to eat!
Philosopher3 says:I am eating now!
Philosopher0put two forks and is ready to think!
Philosopher0 says:I am full and want to think for some time!
Philosopher1get two forks and is ready to eat!
Philosopher1 says:I am eating now!
Philosopher3put two forks and is ready to think!
Philosopher3 says:I am full and want to think for some time!
Philosopher4get two forks and is ready to eat!
Philosopher4 says:I am eating now!
Philosopher1put two forks and is ready to think!
Philosopher1 says:I am full and want to think for some time!
Philosopher2get two forks and is ready to eat!
Philosopher2 says:I am eating now!
Philosopher2put two forks and is ready to think!
Philosopher2 says:I am full and want to think for some time!
Philosopher4put two forks and is ready to think!
Philosopher4 says:I am full and want to think for some time!
Philosopher1get two forks and is ready to eat!
Philosopher1 says:I am eating now!
Philosopher3get two forks and is ready to eat!
Philosopher3 says:I am eating now!
Philosopher1put two forks and is ready to think!
Philosopher1 says:I am full and want to think for some time!
Philosopher0get two forks and is ready to eat!
Philosopher0 says:I am eating now!
Philosopher3put two forks and is ready to think!
Philosopher3 says:I am full and want to think for some time!
Philosopher2get two forks and is ready to eat!
Philosopher2 says:I am eating now!
Philosopher2put two forks and is ready to think!
Philosopher2 says:I am full and want to think for some time!
Philosopher0put two forks and is ready to think!
Philosopher0 says:I am full and want to think for some time!
Philosopher3get two forks and is ready to eat!
Philosopher3 says:I am eating now!
Philosopher1get two forks and is ready to eat!
Philosopher1 says:I am eating now!
Philosopher3put two forks and is ready to think!
Philosopher3 says:I am full and want to think for some time!
Philosopher1put two forks and is ready to think!
Philosopher1 says:I am full and want to think for some time!
Philosopher2get two forks and is ready to eat!
Philosopher2 says:I am eating now!
Philosopher0get two forks and is ready to eat!
Philosopher0 says:I am eating now!
Philosopher2put two forks and is ready to think!
Philosopher2 says:I am full and want to think for some time!
Philosopher3get two forks and is ready to eat!
Philosopher3 says:I am eating now!
Philosopher0put two forks and is ready to think!
Philosopher0 says:I am full and want to think for some time!
Philosopher1get two forks and is ready to eat!
Philosopher1 says:I am eating now!
由结果可以看出,使用了叉子是否被使用这一信号来对哲学家的动作进行控制,并且将注意叉子的使用与安放都需要加锁。因此结果中如果5个人用餐,每次最多两个人用餐,并且是不相邻的两个人,这样就不会出现死锁以及死循环的问题。
1234

被折叠的 条评论
为什么被折叠?



