为了更好地学习线程,通过Java模拟哲学家就餐问题,十分形象,下面是我写的程序,供大家参考:
Philosopher.java
package philosophersproblem;
import java.util.Random;
public class Philosopher extends Thread {
protected Fork left;
protected Fork right;
protected String name;
Philosopher(String nameString, Fork lFork, Fork rFork) {
left = lFork;
right = rFork;
name = nameString;
}
void eat() throws InterruptedException {
java.util.Random r = new Random(System.currentTimeMillis());
System.out.println(name + " begins to eat");
Thread.sleep(Math.round(r.nextDouble() * 2000));
}
void pickupForks() throws InterruptedException {
left.get();
System.out.println(name + " picks up a fork on the left");
right.get();
System.out.println(name + " picks up a fork on the right");
}
void putbackForks() {
left.put();
System.out.println(name + " puts back the fork on the left");
right.put();
System.out.println(name + " puts back the a fork on the right");
}
@Override
public void run() {
while (true) {
try {
pickupForks();
eat();
putbackForks();
} catch (InterruptedException ex) {
}
}
}
}
Fork.java
package philosophersproblem;
public class Fork {
private boolean available = true;
public synchronized void get() throws InterruptedException {
if (!available) {
this.wait();
}
available = false;
}
public synchronized void put() {
available = true;
this.notify();
}
}
Peasant.java
package philosophersproblem;
public class Peasant extends Philosopher {
static ExcuseMe excuseMe = new ExcuseMe();
Peasant(String nameString, Fork lFork, Fork rFork) {
super(nameString, lFork, rFork);
}
@Override
synchronized void pickupForks() throws InterruptedException {
excuseMe.start();
left.get();
System.out.println(name + " picks up a fork on the left");
right.get();
System.out.println(name + " picks up a fork on the right");
excuseMe.end();
}
}
ExcuseMe.java
package philosophersproblem;
public class ExcuseMe {
private boolean excuseme = false;
public synchronized void start() throws InterruptedException {
if (excuseme) {
wait();
}
excuseme = true;
}
public synchronized void end() {
excuseme = false;
notify();
}
}
Main.java
package philosophersproblem;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
/*
Too many philosophers make it less possible to form a dead lock.
Fork f1 = new Fork();
Fork f2 = new Fork();
Fork f3 = new Fork();
Fork f4 = new Fork();
Fork f5 = new Fork();
Philosopher p1 = new Philosopher("p1", f1, f2);
Philosopher p2 = new Philosopher("p2", f2, f3);
Philosopher p3 = new Philosopher("p3", f3, f4);
Philosopher p4 = new Philosopher("p4", f4, f5);
Philosopher p5 = new Philosopher("p5", f5, f1);
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
*/
Fork f1 = new Fork();
Fork f2 = new Fork();
System.out.println("Type 1 to choose philosophers to do the experiment; 2 peasants...");
java.util.Scanner scanner = new Scanner(System.in);
if (scanner.nextInt() == 1) {
Philosopher p1 = new Philosopher("p1", f1, f2);
Philosopher p2 = new Philosopher("p2", f2, f1);
p1.start();
p2.start();
} else {
Peasant p1 = new Peasant("p1", f1, f2);
Peasant p2 = new Peasant("p2", f2, f1);
p1.start();
p2.start();
}
}
}
两位聪明的哲学家,几乎一上来就卡住了,谁都不让谁;换老大粗的农夫,同时把两把叉子都抢过来,他们就永远不会卡了。