Semaphore + mutex
Every philosopher starts by picking the left fork and after that he picks the right one. Without any limitations a deadlock is possible when all philosophers pi
Every philosopher starts by picking the left fork and after that he picks the right one. Without any limitations a deadlock is possible when all philosophers pick the left fork simultaneously. If we limit the number of philosophers who can pick the left fork to 4 there will always be a philosopher who can pick the right fork (the one to the left of a philosopher without any forks).\n```\nclass DiningPhilosophers\n{\n    private Lock forks[] = new Lock[5];\n    private Semaphore semaphore = new Semaphore(4);\n    \n    public DiningPhilosophers()\n    {\n        for (int i = 0; i < 5; i++)\n            forks[i] = new ReentrantLock();\n    }\n    \n    void pickFork(int id, Runnable pick)\n    {\n        forks[id].lock();\n        pick.run();\n    }\n    \n    void putFork(int id, Runnable put)\n    {\n        put.run();\n        forks[id].unlock();\n    }\n    \n    // call the run() method of any runnable to execute its code\n    public void wantsToEat(int philosopher,\n                           Runnable pickLeftFork,\n                           Runnable pickRightFork,\n                           Runnable eat,\n                           Runnable putLeftFork,\n                           Runnable putRightFork) throws InterruptedException\n    {\n        int leftFork = philosopher;\n        int rightFork = (philosopher + 4) % 5;\n        \n        semaphore.acquire();\n        \n        pickFork(leftFork, pickLeftFork);\n        pickFork(rightFork, pickRightFork);\n        eat.run();\n        putFork(rightFork, putRightFork);\n        putFork(leftFork, putLeftFork);\n        \n        semaphore.release();\n    }\n}\n```
[]