Cannibal Dinner Problem in Java

Asked

Viewed 142 times

1

I am doing a college job at Threads and found myself in a complicated situation that since the beginning of the week I do not solve hehehe

The problem is the Cannibais Dinner and I’m developing in Java. I really don’t like ready-made code because it makes learning difficult.

My problem is this: cannibals can’t serve themselves at the same time, but they can eat at the same time. But I think here in mine, all threds are waiting the same Sleep () and the correct is that THREAD CURRENT wait that time.

Following are the classes:

public class Caldeirao {
private int M;

public Caldeirao(int M) {
    this.M = M;
}

public int getM() {
    return M;
}

public void setM(int m) {
    M = m;
}
}

-

public class Canibal extends Thread {

private String nome;
private Caldeirao caldeirao;
private Cozinheiro cozinheiro;
private int qtdComidas = 0;

public Canibal(String nome, Caldeirao caldeirao, Cozinheiro cozinheiro) {
    this.nome = nome;
    this.caldeirao = caldeirao;
    this.cozinheiro = cozinheiro;
}

@Override
public void run() {

    while (true) {

        try {
            this.cozinheiro.Servir(this);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

public String getNome() {
    return nome;
}

public int getQtdComidas() {
    return qtdComidas;
}

public void setQtdComidas(int qtdComidas) {
    this.qtdComidas = qtdComidas;
}

}

-

public class Cozinheiro extends Thread {
private Caldeirao caldeirao;
private int qtdCaldeiraoComplete = 0;

public Cozinheiro(Caldeirao caldeirao) {
    this.caldeirao = caldeirao;
}

@Override
public void run() {
    while (true) {
        try {
            preparaJantar();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

private synchronized void preparaJantar() throws InterruptedException {
    setQtdCaldeiraoComplete(this.getQtdCaldeiraoComplete() + 1);

    while (this.caldeirao.getM() > 0) {
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    System.out.println("Cozinheiro acordado!");
    System.out.println("Cozinheiro preparando o jantar!");

    sleep(5000);

    this.caldeirao.setM(5);
    notify();
}

public synchronized void Servir(Canibal canibal) throws InterruptedException {
    notify();
    if (this.caldeirao.getM() > 0) {
        System.out.println("O canibal " + canibal.getNome() + " está se servindo!");
        Canibal.sleep(1000);
        this.caldeirao.setM(this.caldeirao.getM() - 1);
        Comer(canibal);
    } else {
        notify();
    }

}

public void Comer(Canibal canibal) {
    notify();
    System.out.println("O canibal " + canibal.getNome() + " está comendo!");
    canibal.setQtdComidas(canibal.getQtdComidas() + 1);
    try {
        Canibal.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

public int getQtdCaldeiraoComplete() {
    return qtdCaldeiraoComplete;
}

public void setQtdCaldeiraoComplete(int qtdCaldeiraoComplete) {
    this.qtdCaldeiraoComplete = qtdCaldeiraoComplete;
}

}

-

public class Jantar {

public static void main(String[] args) {
    Caldeirao caldeirao = new Caldeirao(5);

    Cozinheiro cozinheiro = new Cozinheiro(caldeirao);

    Canibal canibal1 = new Canibal("#1", caldeirao, cozinheiro);
    Canibal canibal2 = new Canibal("#2", caldeirao, cozinheiro);
    Canibal canibal3 = new Canibal("#3", caldeirao, cozinheiro);

    cozinheiro.start();

    canibal1.start();
    canibal2.start();
    canibal3.start();

    long inicial = System.currentTimeMillis();

    while ((System.currentTimeMillis() - inicial) <= 120000) {
    }

    cozinheiro.stop();

    canibal1.stop();
    canibal2.stop();
    canibal3.stop();

    System.out.println("O cozinheiro encheu o caldeirao " + cozinheiro.getQtdCaldeiraoComplete());

    System.out.println("O canibal " + canibal1.getNome() + " comeu " + canibal1.getQtdComidas() + " vezes");
    System.out.println("O canibal " + canibal2.getNome() + " comeu " + canibal2.getQtdComidas() + " vezes");
    System.out.println("O canibal " + canibal3.getNome() + " comeu " + canibal3.getQtdComidas() + " vezes");

}

}

My 2 minute duration is coming out:

The cook filled the boiler 4 The cannibal # 1 ate 9 times The cannibal # 2 ate 5 times The cannibal # 3 ate 11 times

My teacher said the average was between 18 and 20.

Would anyone have any idea? Thanks in advance! D

1 answer

0

If you do not want the "serve" action to be executed at the same time then it should not be synchronized. In this case the section below must be modified by the following method:..

public synchronized void Servir(Canibal canibal) throws InterruptedException {
    notify();
    if (this.caldeirao.getM() > 0) {
        System.out.println("O canibal " + canibal.getNome() + " está se servindo!");
        Canibal.sleep(1000);
        this.caldeirao.setM(this.caldeirao.getM() - 1);
        Comer(canibal);
    } else {
        notify();
    }
}

For this:

public void Servir(Canibal canibal) throws InterruptedException {
    notify();
    if (this.caldeirao.getM() > 0) {
        System.out.println("O canibal " + canibal.getNome() + " está se servindo!");
        Canibal.sleep(1000);
        this.caldeirao.setM(this.caldeirao.getM() - 1);
        Comer(canibal);
    } else {
        notify();
    }
}

This way, the threads when they consume this guy, will wait to run one at a time, as a sort of queue.

I hope I’ve helped.

  • Yeah, I tried. When I change it, it gives me the following error: java.lang.Illegalmonitorstateexception

  • Try to separate the serve method into a new class, and instate it later, consider using a Singleton.

  • Yeah, it’s working. I’ll keep testing here all night. It must be bullshit that I’m not notifying. Because ALL processes are waiting for Sleep and not just one. Thanks anyway! : D

  • Right, and I don’t have a way to spin it right now, but tonight I’m gonna take a little time and spin this around and help you. :)

  • Oh man, thank you so much! Really :) I will stay here on duty until tomorrow time to present the work hehehe :D

Browser other questions tagged

You are not signed in. Login or sign up in order to post.