Ajuda monitores java dando Starvation

meu codigo ta dando starvation, no caso os homens ficam esperando e nunca entram no “banheiro”, poderiam me ajudar? estou usando o wait e notify de forma errada?

segue o codigo:

CLASSE BANHEIRO

public class Banheiro extends Thread{
    private static int homensDentro;  
    private static int mulheresDentro;  
    private static int filaHomem;  
    private static int filaMulher;  
    private static int sexo;  
      
    public Banheiro(int sexo) {  
        mulheresDentro = 0;  
        homensDentro = 0;  
        filaHomem = 0;  
        filaMulher = 0;  
        this.sexo = sexo;  
    }  
      
    public synchronized void filaBanheiro(int sexo) {  
          
        switch (sexo) {  
          
        case 1: if (filaHomem < 10)  
                    filaHomem++;              
              
        case 2: if (filaMulher < 10)  
                    filaMulher++;  
          
        }  
    }  
      
      
    public synchronized void entraBanheiro(int sexo) {  
          
        switch (sexo) {  
          
        case 1: if (homensDentro < 3 && mulheresDentro == 0 && filaMulher == 0) {  
            // TODO Auto-generated catch block
              
                      
            filaHomem--;
            homensDentro++;
            System.out.println("Um homem entrou no banheiro, total de " + homensDentro + " homem(ns)");  
                } else if (homensDentro == 3)  
                    System.out.println("Já existem 3 homens ocupando o banheiro" );  
                    else if (mulheresDentro > 0)  
                        System.out.println("Homem, não entre! Pois existe(m) " + mulheresDentro + " mulher(es) no banheiro");  
          
        case 2: if (mulheresDentro < 3 && homensDentro == 0) {  
                      
                    try {  
                        filaMulher--;  
                        mulheresDentro++;  
                        System.out.println("Uma mulher entrou no banheiro, total de " + mulheresDentro + " mulher(es)" );  
                        wait(10);  
                    } catch (InterruptedException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    }  
                } else if (mulheresDentro == 3)  
                    System.out.println("Já existem 3 mulheres ocupando o banheiro" );  
                    else if (homensDentro > 0)  
                        System.out.println("Mulher, não entre! Pois existe(m) " + homensDentro + " homem(ns) no banheiro" );
        }         
    }  
      
  
    public synchronized void saiBanheiro(int sexo) {  
          
        switch (sexo) {  
          
        case 1: if (homensDentro > 0) {  
                    homensDentro--;  
                    System.out.println("Um homem saiu do banheiro, total de " + homensDentro + " homem(en)" );
                    notify();  
                }  
          
        case 2: if (mulheresDentro > 0) {  
                    mulheresDentro--;  
                    System.out.println("Uma mulher saiu do banheiro, total de " + mulheresDentro + " mulher(es)" );
                    notify();  
                }         
        }  
    }  
      
    public void run() {  
          
        for (int i=0; i<10; i++) {     
            if (sexo == 1) {  
                try {  
                    filaBanheiro(sexo);  
                    entraBanheiro(sexo);  
                    sleep((long) (Math.random() * 2));  
                    saiBanheiro(sexo);  
                    sleep((long) (Math.random() * 2));  
                } catch (InterruptedException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                  }  
            } else {  
                try {  
                    filaBanheiro(sexo);  
                    entraBanheiro(sexo);  
                    sleep((long) (Math.random() * 2));  
                    saiBanheiro(sexo);  
                      
                } catch (InterruptedException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                  }               
            }  
        }  
    
    
    
    
    }
}
MAIN
public class Exbanheiro2 {

   
    public static void main(String[] args) {
        Banheiro mulher = new Banheiro(2);  
        Banheiro homem = new Banheiro(1);  
          
        homem.start();  
        mulher.start();       
       
    }
    
}

eu acho estranho vc colocar sexo 1 e 2

poderia ser boolean masculino e todos os switch cases viram if/ else

o switch tem tem a caracteristica de, uma vez que encontrou o case ele executa todos os switchs abaixo.

isso:

		int i = 3 ;
		switch(i) {
			case 1: System.out.println(1);
			case 2: System.out.println(2);
			case 3: System.out.println(3);
			case 4: System.out.println(4);
			case 5: System.out.println(5);
			case 6: System.out.println(6);
			case 7: System.out.println(7);
			default: System.out.println("nao achei");
		}

vai imprimir

3
4
5
6
7
nao achei

pra evitar isso a galera coloca um break antes do proximo case. ai evita que “caia ate o final”.

revise seu codigo e veja se isso te da alguma vantagem. se ainda continuar entao tente explicar sua logica pq eu li e fiquei com um pouco confuso ( justamente pelo switch, ifs, etc )

como assim boolean masculino? se o sexo for == masculino retorna true e o homem entra no banheiro caso contrario a mulher entra ?

meu amigo pra que fazer sexo ser 1 e 2 se no lugar vc pode criar uma variavel “masculino” e se for true, é homem, caso contrario sera mulher?

pq sexo 1 e 2 é uma gambiarra, seria menos ruim se vc usasse char ‘m’ ou ‘f’ pq ai tem algum sentido. outra forma de deixar o seu codigo expressivo é usando Enumerações.

mas enfim, deixa pra la se vc nao entendeu. importante é vc ver que switch/case nao funciona exatamente como vc quer.

agradeço “meu amigo”, só lembrando que a intenção desse programa não é ser didático, apenas um exercício, mas como deu pra tu entender que 1 é homem e 2 é mulher é sinal de que há algum sentido

Claro, mas se vc usa 1 e 2 e mete um switch case sem break não funciona exatamente como vc quer.

E debugar threads é punk - quanto mais simples o código melhor.

Por exemplo eu ja tive bugs que levei semanas pra resolver pois a modelagem estava errada e eu não via certas coisas (como o fato de algumas operações serem curto-circuitadas). Semanas de ponta-pé do chefe. Quando eu vejo algo que pode ser A ou B então é melhor usar algo adequado (pq eu lembro da dor daqueles bugs). Mas pra exercício esta sussa :slight_smile:

Detalhe que estou batendo na tecla do “break” no seu switch e vc nem disse se isso resolveu ou te deu outro problema…

A forma como você implementou seu exercício não me parece coerente.

Você criou dois Banheiros que executam concorrentemente incrementando valores correspondentes aos homens e às mulheres.

Acredito que sua atividade seja implementar o acesso a um único banheiro unissex.
Neste caso, o Banheiro deveria ser somente um recurso.
A fila de pessoas querendo usar o banheiro é que seria o processo concorrente.

Eu criaria:

  • uma única instancia de Banheiro;
  • uma Fila de Pessoas contendo homens e mulheres;
  • em seguida dispararia uma Thread que iterasse sobre essa fila de pessoas tentando fazer cada uma acessar o Banheiro.