Problem Thread Synchronization

0

I have a problem with the synchronization of threads in java, I comment.

I am trying to make a program such that I have an array of threads and I execute them all at the same time and whose only function is to move the position of a JLabel as if it were a race, the problem is that I have to launch all the threads and I have to do that until one of them has not taken a step do not move the next and that is to say that if I have 5 threads because the thread 2 takes a step and until it does not finish taking the step does not start step of another and so on until it reaches the goal but I can not get it to work well, I show you the code:

  

CONTROLLER CLASS: IT IS EVERYTHING I EXECUTE AND THAT CONTAINS MY ARRAY OF    THREADS IN THE WINDOW CLASS

public class Controlador extends Thread {

@Override
public void run() {
//Ficha es un JLabel que contiene la imagen del corredor
//Ventana es el JFrame sobre el que se encuentran los JLabel 
    int delay = generarNumeroAleatorio();

        while (!ventana.haLlegado(ficha)) {
        //ventana.haLlegado devuelve true o false si ha llegado al final de la pantalla
                ventana.movimientoSincronizado(this);
                try {
                    Thread.sleep(delay);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                    SwingUtilities.invokeLater(() -> {
                        ventana.mover(ficha); 
                    });


        }
    }
  

WINDOW CLASS: CONTAINS THE COMPONENT AND EXTENDS FROM JFRAME

public class Ventana extends JFrame implements ActionListener {

private boolean poderMoverse;
private Controlador[] hilos = new Controlador[8];


public void mover(JLabel ficha)
{
    ficha.setLocation(ficha.getX() + 50 , ficha.getY());
}
public synchronized boolean movimientoSincronizado(Controlador corredor)
{
    while (!poderMoverse) //Mientras no pueda moverse dejo el hilo en espera
    {
        try {
 //Cada hilo tiene como nombre la posicion que ocupa dentro del array
            int id = Integer.valueOf(corredor.getName());
            hilos[id].wait();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    poderMoverse = true; //Cambio el valor para que pueda moverse
    notifyAll();
    return poderMoverse;
}

I hope you can help me, Thank you very much everyone

    
asked by Josemanuu 25.11.2018 в 22:53
source

1 answer

0

Interesting. For this case create a JFrame (Careers) to perform the functional test.

This is the code autogenerated by Netbeans and inside the constructor I made the modifications

public Carreras() {
    initComponents();

    // Este hilo es necesario para separar cualquier proceso del principal de la ventana grafica. Evita que se congele.
    Thread hiloBase = new Thread(new Runnable() {
        @Override
        public void run() {

            // todos los caballos son jLabel
            iniciarCarrera(caballo1, 1);
            iniciarCarrera(caballo2, 3);
            iniciarCarrera(caballo3, 2);
            iniciarCarrera(caballo4, 4);
            iniciarCarrera(caballo5, 1);


        }
    });


    hiloBase.start();


}

And this is the method that applies to make each race independent. You can place it where you want (For the test, put it before the constructor as an additional method)

public void iniciarCarrera(final JLabel caballo, int velocidad) {
    System.out.println("Iniciando carrera: " + caballo.getText());
    // Un hilo para cada elemento para independizarlos de los demas procesos e hilo base.  
    Thread carrera = new Thread(() -> {
        System.out.println("iniciado");
        int pasos = velocidad;
        while (pasos <= 100) {
            final int pasosdados = pasos;
            try {
                //cambios en el UI se deben hacer mediante el Event Dispatch Thread
                SwingUtilities.invokeAndWait(() -> {
                    caballo.setLocation(pasosdados, caballo.getY()); // desplazamiento del jlabel
                });
            } catch (InterruptedException | InvocationTargetException ex) {
                Logger.getLogger(Carreras.class.getName()).log(Level.SEVERE, null, ex);
            }
            pasos += velocidad;

            try { // solo para que se vea lento
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(Carreras.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }, caballo.getText());
    carrera.start();
}

Finally, if your thing is learning to develop games, I recommend GODOT 3.

    
answered by 26.11.2018 / 00:04
source