Java Threads Test (elementary) does not seem to work correctly

-1

This is a thread synchronization test and the output I get is this:

The code I am using is this:

compartirinf.java

package cuenta;

public class CompartirInf{ // Esto es el programa principal
public static void main(String[] args){
    Cuenta c=new Cuenta(40,500); 
    Persona p1=new Persona ("Ana",c);
    Persona p2=new Persona ("Juan",c);

    p1.start();
    p2.start();
}


}

cuenta.java

package cuenta;

class Cuenta{
    private int saldo;
    private int max_saldo;

    //constructor
    Cuenta (int s,int m)
    {
        saldo=s; //inicializa el saldo actual
        max_saldo=m;
    }//--------------------------------------


    //devuelve el saldo 
    int getSaldo()
    {
        return saldo; //
    }



    // sumar la cantidad al saldo
    void sumar(int cantidad)
    {
        saldo += cantidad;
    }//-----------------------------------


    // resta la cantidad al saldo
    void restar(int cantidad)
    {
        saldo=saldo-cantidad;
    }//-----------------------------------


    //comprueba se pueda retirar dinero  y lo retira
        public synchronized void Reintegro(int cant,String nom)
    {
    if (getSaldo()<cant) //si no hay suficiente saldo muestro mensaje
        System.out.println (nom +" quiere retirar "+ cant+" dinero no hay saldo suficiente . Saldo Actual: "+ getSaldo() +"");

    while (getSaldo()<cant){ //si no hay bastante saldo espero
        try {
            wait();
        }catch (InterruptedException e){};
    }

    System.out.println (" Se va a retirar saldo (actual es: "+ getSaldo() +")");
            try {
                Thread.sleep(500);
                } catch (InterruptedException ex) {}
    restar (cant);
      notifyAll();
    System.out.println (nom +" retira => : "+cant +". Saldo Actual: "+ getSaldo() +"");

    }// fin retirar dinero------------------------------



    //comprueba se pueda insertar dinero  y lo ingresa
    public synchronized void Ingreso(int cant,String nom){


        // Si el saldo es menor a la cantidad límite lo ingresa en la cuenta del objeto persona
        //max_saldo
        if ((cant+getSaldo())<max_saldo) //si no hay suficiente saldo muestro mensaje
        System.out.println (nom +" quiere retirar "+ cant+" dinero es superior al saldo máximo permitido . Saldo Actual: "+ getSaldo() +"");
    while ((cant+getSaldo())<max_saldo){ //si el saldo a ingresar es superior al saldo máximo
        try {
            wait();
        }catch (InterruptedException e){};
    }
        System.out.println (" Se va a añadir saldo (actual es: "+ getSaldo() +")");
            try {
                Thread.sleep(500);
                } catch (InterruptedException ex) {}
    sumar (cant);
      notifyAll();
    System.out.println (nom +" añade => : "+cant +". Saldo Actual: "+ getSaldo() +"");
    }
    }

person.java

package cuenta;

import java.util.Random;
class Persona extends Thread{
private Cuenta c; //declaro objeto cuenta c
private String nom;
int dinero;

//constructor
public Persona (String n, Cuenta c){
//      super(n);
    this.c=c;
    nom=n;
}
//run
public void run(){
Random rnd = new Random();
        dinero=(int)(rnd.nextDouble() * 501.0);
        c.Ingreso (dinero,nom);

        dinero=(int)(rnd.nextDouble() * 501.0);
        c.Reintegro(dinero,nom);

        dinero=(int)(rnd.nextDouble() * 501.0);
        c.Ingreso (dinero,nom);

        dinero=(int)(rnd.nextDouble() * 501.0);
        c.Reintegro(dinero,nom);
    }


}

The purpose is to get an execution where the movements of adding money to the account, not just withdrawal, are also shown. However, it seems that the thread stops at some point and does not show the actions that it is supposed to do.

Any clue as to what could be failing?

    
asked by heptagono 08.11.2017 в 18:13
source

1 answer

1

With the messages you received, it is very easy to find the cause of the error.

Part of the problem is the management of your threads, it is true, but mainly it is that your logic is not right. Both threads are stuck in the same place when executing the first call to Ingreso :

public synchronized void Ingreso(int cant,String nom){
    // Si el saldo es menor a la cantidad límite lo ingresa en la cuenta del objeto persona
    //max_saldo
    if ((cant+getSaldo())<max_saldo) //si no hay suficiente saldo muestro mensaje
        System.out.println (nom +" quiere retirar "+ cant+" dinero es superior al saldo máximo permitido . Saldo Actual: "+ getSaldo() +"");

    while ((cant+getSaldo())<max_saldo) { //si el saldo a ingresar es superior al saldo máximo
        try {
            wait(); // <------- se tranca aquí!!!
        } catch (InterruptedException e){};
    }

    // ...
}

More precisely, the call to wait() is blocked. This is due to the condition:

cant+getSaldo())<max_saldo

... that according to the messages you received, have the following values:

341+40 < 500 // Ana
145+40 < 500 // Juan

The first problem is that I do not think that is the condition you want here. Rather, it is most likely the reverse condition:

cant+getSaldo())>max_saldo

But even if you correct it, you must assume that the condition can become true depending on the value of cant , which leads to the next point ...

Once the 2 threads make wait() , you need another thread that is still active, that removes enough money, and that you call notifyAll() to wake up the threads locked. Obviously, this does not happen in your case because the 2 threads get stuck while trying to add money.

I can not give you a solution to this problem, because I think that, basically, you may not have understood correctly the exercise that was asked of you.

But if you at least reverse that erroneous condition, you should see that the threads work a little more than before. But it seems that you will have to debug and correct more problems later.

    
answered by 08.11.2017 / 21:16
source