import java.util.concurrent.
Semaphore;
class DiningPhilosophers {
static class Fork {
Semaphore semaphore = new Semaphore(1);
}
static class Philosopher extends Thread {
private final int id;
private final Fork leftFork, rightFork;
private final int totalPhilosophers;
// Default constructor will be used implicitly, but params are passed
during initialization.
Philosopher(int id, Fork leftFork, Fork rightFork, int totalPhilosophers) {
this.id = id;
this.leftFork = leftFork;
this.rightFork = rightFork;
this.totalPhilosophers = totalPhilosophers;
}
@Override
public void run() {
try {
while (true) {
think();
takeForks();
eat();
putDownForks();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void think() throws InterruptedException {
System.out.println("Philosopher " + id + " is thinking.");
Thread.sleep((int) (Math.random() * 1000));
}
private void takeForks() throws InterruptedException {
if (id == totalPhilosophers - 1) {
rightFork.semaphore.acquire();
System.out.println("Philosopher " + id + " picked up right fork.");
leftFork.semaphore.acquire();
System.out.println("Philosopher " + id + " picked up left fork.");
} else {
leftFork.semaphore.acquire();
System.out.println("Philosopher " + id + " picked up left fork.");
rightFork.semaphore.acquire();
System.out.println("Philosopher " + id + " picked up right fork.");
}
}
private void eat() throws InterruptedException {
System.out.println("Philosopher " + id + " is eating.");
Thread.sleep((int) (Math.random() * 1000));
}
private void putDownForks() {
leftFork.semaphore.release();
rightFork.semaphore.release();
System.out.println("Philosopher " + id + " put down forks.");
}
}
public static void main(String[] args) {
final int NUM_PHILOSOPHERS = 5;
Fork[] forks = new Fork[NUM_PHILOSOPHERS];
for (int i = 0; i < NUM_PHILOSOPHERS; i++) forks[i] = new Fork();
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
new Philosopher(i, forks[i], forks[(i + 1) % NUM_PHILOSOPHERS],
NUM_PHILOSOPHERS).start();
}
}
}