Thread objects not syncing

97 views Asked by At

So I wrote this program to run multiple threads of this robot class using cyclicbarrier to sync the threads. Since I had very little understanding of cyclicbarrier I assumed it would automatically sync up my threads, but it seems not. What do I have to do for my Robot threads to sync based on my progress integer value?

public class Robot implements Runnable{
public static final int on = 0x0001;
public static final int clockwise = 0x0002;
public static final int counter = 0x0004;
int  opcode;
int moveCount = 0;
int rotation, increment, progress = 0;
boolean CW;

ProgressBar prgBar;
CyclicBarrier cyclicBarrier;
Controller c;
Motor m;

public Robot(CyclicBarrier cyclicBarrier, Motor m)
{
    opcode = 0;
    this.cyclicBarrier = cyclicBarrier;
    this.m = m;
}




public void run(){
    System.out.println("Running: ");

    try {
        while(progress <= 24){
            i = m.Engage(this, i, increment/4);
            prgBar.setProgress(this, progress);
        }
        System.out.println("Sleeping: ");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+ " waiting at barrier 1");
        cyclicBarrier.await();

        while(progress <= 49){
            i = m.Engage(this, i, increment/2);
            prgBar.setProgress(this, progress);
        }
        System.out.println("Sleeping: ");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+ " waiting at barrier 2");
        cyclicBarrier.await();

        while(progress <= 74){
            i = m.Engage(this, i, ((increment/4)*3));
            prgBar.setProgress(this, progress);
        }
        System.out.println("Sleeping: ");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+ " waiting at barrier 3");
        cyclicBarrier.await();

        while(progress <= 99){
            i = m.Engage(this, i, increment);
            prgBar.setProgress(this, progress);
        }
        System.out.println("Sleeping: ");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+ " waiting at barrier 4");
        cyclicBarrier.await();

    } catch (Exception e){
        e.printStackTrace();
    }
    prgBar.setProgress(this, progress);
    System.out.println("Engaging: ");
}

public class Controller {

public static void main(String[] args){
    CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
    Motor m = new Motor();


    Robot xRob = new Robot(cyclicBarrier, m);
    Robot yRob = new Robot(cyclicBarrier, m);
    Robot zRob = new Robot(cyclicBarrier, m);

    Thread xRobThread = new Thread(xRob);
    Thread yRobThread = new Thread(yRob);
    Thread zRobThread = new Thread(zRob);

    boolean clockwise = true, counterClockwise = false;




    m.setMotor(clockwise, 14400, xRob);
    m.setMotor(clockwise, 7200, yRob);
    m.setMotor(counterClockwise, 28800, zRob);

    xRobThread.start();
    yRobThread.start();
    zRobThread.start();

    try {
        xRobThread.join();
        yRobThread.join();
        zRobThread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }


    System.out.printf("x = %d y = %d z = %d\n\n", xRob.moveCount, yRob.moveCount, zRob.moveCount);

}
}
2

There are 2 answers

3
Solomon Slow On

What does the program do when you run it? What were you expecting it to do? (i.e., what do you think "sync up my threads" means?)

At least, your update now contains enough information for me to make a guess, and I'm guessing that the program hangs. Your main() routine creates a new CyclicBarrier for four parties, and then it creates three threads. Each of those threads calls cyclicBarrier.await(), but I don't see any fourth party. The barrier won't open until four threads have called await().


Additional info:

OK, so let's say you have a loop that makes some kind of "progress". You can have the first thread that reaches a certain threshold of progress wait for the others to catch up by doing something like this:

double progress = 0.0;
static final double CHECKPOINT = 0.5;
static final double FINISHED = 1.0;
boolean reachedCheckpoint = false;

while (progress < FINISHED) {
    progress = makeSomeProgress();
    if (! reachedCheckpoint && progress >= CHECKPOINT) {
        cyclicBarrier.await();
        reachedCheckpoint = true;
    }
}

Obviously, the program will be somewhat more complicated if you want to have more than one checkpoint, but that's the basic idea. Just remember that the number of "parties" for which the CyclicBarrier was constructed has to be exactly equal to the number of threads that actually are using it.

0
Arian.No On

I set barrier1 as ~25%, and barrier2 as ~50% and so on, of how far I want to go in the loop and I update i by outputting the current place in the lop when it reaches the end for each thread. I do the same thing over and over again until it reaches the end of progress.

public void run(){
    System.out.println("Running: ");
    barrier1 = increment/4;
    barrier2 = increment/2;
    barrier3 = ((increment/4)*3);
    barrier4 = increment;
    try {
        i = m.Engage(this, i, barrier1);
        prgBar.setProgress(this, progress);

        System.out.println("Sleeping: ");
        Thread.sleep(1000);
        System.out.println(Thread.currentThread().getName()+ " waiting at barrier 1");
        cyclicBarrier.await();


        i = m.Engage(this, i, barrier2);
        prgBar.setProgress(this, progress);

        System.out.println("Sleeping: ");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+ " waiting at barrier 2");
        cyclicBarrier.await();


        i = m.Engage(this, i, barrier3);
        prgBar.setProgress(this, progress);

        System.out.println("Sleeping: ");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+ " waiting at barrier 3");
        cyclicBarrier.await();


        m.Engage(this, i, barrier4);
        prgBar.setProgress(this, progress);

    } catch (Exception e){
        e.printStackTrace();
    }
    prgBar.setProgress(this, progress);
    System.out.println(Thread.currentThread().getName()+ " closing.");
    Thread.currentThread().interrupt();
    System.out.println("Engaging: ");
}