0

所以我写了这个程序来运行这个机器人类的多个线程,使用 cyclicbarrier 来同步线程。由于我对循环障碍知之甚少,我认为它会自动同步我的线程,但似乎不是。我需要做什么才能让我的机器人线程根据我的进度整数值进行同步?

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 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);

}
}
4

2 回答 2

1

程序运行时会做什么?你期待它做什么?(即,您认为“同步我的线程”是什么意思?)

至少,您的更新现在包含足够的信息让我猜测,我猜该程序挂起。您的 main() 例程为四方创建一个新的 CyclicBarrier,然后创建三个线程。这些线程中的每一个都调用 cyclicBarrier.await(),但我没有看到任何第四方。在四个线程调用 await() 之前,屏障不会打开。


附加信息:

好的,假设您有一个循环,可以实现某种“进步”。您可以通过执行以下操作让第一个达到特定进度阈值的线程等待其他线程赶上:

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;
    }
}

显然,如果您想拥有多个检查点,程序会稍微复杂一些,但这是基本思想。请记住,构造 CyclicBarrier 的“参与方”的数量必须完全等于实际使用它的线程数。

于 2014-11-24T08:30:40.280 回答
0

我将barrier1设置为~25%,将barrier2设置为~50%,依此类推,我想在循环中走多远,我通过在每个线程到达末尾时输出lop中的当前位置来更新i。我一遍又一遍地做同样的事情,直到进度结束。

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: ");
}
于 2014-11-24T10:04:42.860 回答