线程对象不同步

时间:2014-11-24 07:28:31

标签: java multithreading cyclicbarrier

所以我编写了这个程序来运行这个机器人类的多个线程,使用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);

}
}

2 个答案:

答案 0 :(得分:1)

运行程序时程序会执行什么操作?你期待它做什么? (即,您认为&#34;同步我的线程&#34;意味着什么?)

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


其他信息:

好的,所以让我们说你有一个循环可以带来某种进步&#34;。您可以让第一个达到某个进度阈值的线程等待其他人赶上这样做:

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

显然,如果你想拥有多个检查点,程序会更复杂,但这是基本的想法。请记住&#34;派对的数量&#34;为其构造CyclicBarrier必须与实际使用它的线程数完全相等。

答案 1 :(得分:0)

我将barrier1设置为~25%,barrier2设置为~50%等等,我想在循环中走多远,并且当它到达每个端点时,通过输出当前位置来更新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: ");
}