Do problem 12.27.
Specifically, start with the class Philosopher. The main() method here creates five forks, then creates five Philosophers and runs them sequentially. This works fine, but does not take advantage of concurrency.
Notice that the eat() method uses a synchronized block to gain exclusive access to one fork, then grabs another fork, then eats, and then puts back the forks.
This is a problem if, as in the main() method from Deadlock, we run the Philosophers in different threads. Often they will each pick up their left fork and nobody will be able to proceed.
Write a class ConcurrentPhilosopher that extends Philosopher. It should have:
A main() method that is just like the one in Deadlock, but creates ConcurrentPhilosophers instead of Philosophers.
A constructor that simply calls the super constructor, passing along the arguments.
An overridden version of eat() that accomplishes the same task as the one in Philosopher, but uses the ReentrantLocks in the forks array to avoid deadlock. Notice that eat() returns a boolean indicating whether it succeeded; the run() method from Philosopher takes care of waiting for a fraction of a second and trying again if an eating attempt fails.
You are not permitted to modify either of the existing classes.
Hand in your program ConcurrentPhilosopher.java. All files are in the package a8.