Question

I have a problem in my Java code that should simulate dining pholosophers problem, which is described here: http://en.wikipedia.org/wiki/Dining_philosophers_problem I want to output the current state of all philosophers every time one of them eats or thinks. Output should look something like this: "O X O o X (2)", where "X" means that philosopher eats, "O" means that he is thinking, and "o" means that he is waiting for chopsticks. The number in brackets indicates the number of the philosopher whose state has changed. The problem that I have is that only philosophers 1 and 3 (sometimes 2 and 4) eat, while others always think or wait for forks, and that repeats constantly, so the output looks like this:

O X O O O (2)

o X o X O (4)

o O o X o (2)

o O o O o (4)

o X o O o (2)

o X o X o (4)

o O o X o (2)

...

Complete code is here:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Stick{
    boolean available;
    public Stick(){
        available = true;
    }
    public void setAvailability(boolean flag){
        this.available = flag;
    }
    public boolean getAvailability(){
        return available;
    }
}

class Philosopher extends Thread{
    private int id;
    private Stick l, r;
    private Lock monitor;
    private Condition[] cond;
    private Problem p;

    private void outputState(int _id){
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<5; i++)
            sb.append(p.getState(i) + " ");
        System.out.println(sb + "(" + (_id+1) + ")");
    }

    private void takeChopSticks(int _id) throws InterruptedException{
        monitor.lock();
        try{
            p.setState(_id, "o");
            while(!l.getAvailability() || !r.getAvailability()){
                cond[_id].await();
            }
            l.setAvailability(false);
            r.setAvailability(false);
            p.setState(_id, "X");
            outputState(_id);
        }finally{
            monitor.unlock();
        }
    }

    private void eat() throws InterruptedException{
        Thread.sleep(1000);
    }

    private void think(int _id) throws InterruptedException{
        Thread.sleep(2000);
    }

    public void run(){
        while(true){            
            try{
                takeChopSticks(this.id);
                eat();
                releaseChopSticks(this.id);
                think(this.id);
            }catch(InterruptedException e){System.out.println("srusila se metoda run()");}

        }
    }

    private void releaseChopSticks(int _id) throws InterruptedException{
        monitor.lock();
        try{
            l.setAvailability(true);
            r.setAvailability(true);
            cond[_id].signalAll();
            cond[(_id+4)%5].signalAll();
            p.setState(_id, "O");
            outputState(_id);
        }finally{
            monitor.unlock();
        }
    }

    public Philosopher(Problem _p, int _id, Stick _l, Stick _r, Lock m){
        cond = new Condition[5];
        monitor = m;
        id = _id;
        l = _l;
        r = _r;
        p = _p;
        for(int i=0; i<5; i++)
            cond[i] = monitor.newCondition();
    }
}

public class Problem {
    Thread[] t;
    Stick[] s;
    private enum State {O, X, o};
    private State[] state;

    public State getState(int id){
        return state[id];
    }

    public void setState(int id, String s){
        if(s == "o")
            state[id] = State.o;
        else if(s=="O")
            state[id] = State.O;
        else if(s=="X")
            state[id] = State.X;
    }

    public Problem(){
        state = new State[5];
        t = new Thread[5];
        s = new Stick[5];
        for(int i=0; i<5; i++){
            s[i] = new Stick();
            state[i] = State.O;
        }
        Lock m = new ReentrantLock();
        for(int i=0; i<5; i++)
            t[i] = new Philosopher(this, i, s[i], s[(i+4)%5], m);
        for(int i=0; i<5; i++)
            t[i].start();

    }

    public static void main(String[] args){
        new Problem();
    }
}

I know there are allready several questions about dining philosophers in Java, but none of them seem to help, and my code is a bit different. Thanks.

Was it helpful?

Solution

I've modified it quite a bit and it finally works. The code is:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Chopstick{
    private boolean availability;

    public Chopstick(){
        availability = true;
    }

    public boolean getAvailability(){
        return availability;
    }

    public void setAvailability(boolean flag){
        availability = flag;
    }
}

class Helper{
    private Lock mutex = null;
    private Condition[] cond;
    private String[] state;
    private int[] id;

    private void outputState(int id){
        StringBuffer line = new StringBuffer();
        for(int i=0; i<5; i++)
            line.append(state[i] + " ");
        System.out.println(line + "(" + (id+1) + ")");
    }

    public Helper(){
        id = new int[5];
        mutex = new ReentrantLock();
        state = new String[5];
        cond = new Condition[5];
        for(int i=0; i<5; i++){
            id[i] = i;
            state[i] = "O";
            cond[i] = mutex.newCondition();
        }
    }

    public void setState(int id, String s){
        state[id] = s;
    }

    public void grabChopsticks(int id, Chopstick l, Chopstick r){
        mutex.lock();
        try{
            setState(id, "o");
            while(!l.getAvailability() || !r.getAvailability())
                cond[id].await();

            l.setAvailability(false);
            r.setAvailability(false);
            setState(id, "X");
            outputState(id);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            mutex.unlock();
        }
    }


    public void releaseChopsticks(int id, Chopstick l, Chopstick r){
        mutex.lock();
        try{
            setState(id, "O");
            l.setAvailability(true);
            r.setAvailability(true);
            cond[(id+1)%5].signalAll();
            cond[(id+4)%5].signalAll();
            outputState(id);
        }finally{
            mutex.unlock();
        }
    }
}


class Philosopher implements Runnable{
    private Helper hlp;
    private Chopstick l, r;
    private int id;
    public Philosopher(int id, Chopstick l, Chopstick r, Helper i){
        this.hlp = i;
        this.l = l;
        this.r = r;
        this.id = id;
    }

    private void eat(){
        try{
            Thread.sleep(2000);
        }catch(InterruptedException e){}
    }

    private void think(){
        try{
            Thread.sleep(2000);
        }catch(InterruptedException e){}
    }

    public void run(){
        while(true){
            hlp.grabChopsticks(id, l, r);
            eat();
            hlp.releaseChopsticks(id, l, r);
            think();
        }
    }
}

public class Problem {
    private Chopstick[] s;
    private Philosopher[] f;
    private Helper hlp;

    private void init(){
        s = new Chopstick[5];
        f = new Philosopher[5];
        hlp = new Helper();
        for(int i=0; i<5; i++)
            s[i] = new Chopstick();

        for(int i=0; i<5; i++){
            f[i] = new Philosopher(i, s[i], s[(i+4)%5], hlp);
            new Thread(f[i]).start();
        }

    }

    public Problem(){
        init();
    }

    public static void main(String[] args){
        new Problem();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top