- 直接对筷子资源进行加锁,只允许一个人同时吃,这种情况只能同时一个人吃
public class PerThread extends Thread {
private static int[] chopstick = { 1, 1, 1, 1, 1 };
private int i;
public PerThread(int i) {
this.i = i;
}
@Override
public void run() {
synchronized (chopstick) {
eat(this.getName());
think(this.getName());
}
}
private void think(String name) {
chopstick[i] = 1;
chopstick[(i + 1) % 5] = 1;
System.out.println("per"+name+" is thinking...");
}
private void eat(String string) {
while (true) {
if (chopstick[i] != 0) {
chopstick[i]--;
System.out.println("per" + this.getName()
+ " got left chopstick.");
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
if (chopstick[(i + 1) % 5] != 0) {
chopstick[(i + 1) % 5]--;
System.out.println("per" + this.getName()
+ " got right chopstick.");
break;
}
}
System.out.println("per" + string + " is eating...");
}
}
测试程序
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 0; i < 5; i++) {
Thread t = new PerThread(i);
t.start();
}
}
}
2.每个哲学家必须确定自己左右手的筷子都可用的时候,才能同时拿起两只筷子进餐,吃完之后同时放下两只筷子。可以看到最多只能有两条相邻的eating结果,因为每个时刻最多能够满足两个人同时进餐,且两人座位不相邻
class Fork{
/*5只筷子,初始为都未被用*/
private boolean[] used={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) {
// TODO Auto-generated catch block
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();//唤醒其他线程
}
}
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){
thinking();
fork.takeFork();
eating();
fork.putFork();
}
}
public void eating(){
System.out.println("I am Eating:"+name);
try {
sleep(1000);//模拟吃饭,占用一段时间资源
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void thinking(){
System.out.println("I am Thinking:"+name);
try {
sleep(1000);//模拟思考
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试程序
public class Test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
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();
}
}