2014-11-24 92 views
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); 

} 
} 
+6

因爲我對循環屏障的理解很少,我認爲它會自動同步我的線程,但它似乎不是._你認真嗎?請閱讀javadoc。 – 2014-11-24 07:30:16

+0

我用過去式,現在明白了,情況並非如此。我也多次閱讀過它,對我來說沒有任何意義,因爲我的代碼與他們的例子並不完全相同。他們也沒有真正解釋如何在基於障礙點的變量之間分配工作。 – 2014-11-24 07:48:01

+0

問題是,你認爲「同步我的線程」應該是什麼意思?也就是說,你期望這個班級做什麼?它做什麼呢?爲什麼這會讓你感到驚訝?如果您向我們展示完整的程序,它可能會有很大的幫助。你只向我們展示了一個使用CyclicBarrier的類。您沒有向我們展示CyclicBarrier的創建,也沒有向我們展示創建任何運行您的Robot類的線程。 – 2014-11-24 08:05:47

回答

1

是什麼,當你運行它的程序呢?你在想什麼它要做什麼? (即,你認爲「同步我的線程」是什麼意思?)

至少,您的更新現在包含足夠的信息讓我猜測,並且我猜測程序掛起。您的main()例程爲四方創建一個新的CyclicBarrier,然後創建三個線程。每個線程調用cyclicBarrier.await(),但我沒有看到任何第四方。在四個線程調用await()之前,屏障不會打開。


附加信息:

OK,讓我們假設你有一個循環,使某種形式的「進步」。你可以到達的進展等待一定的閾值的第一個線程爲他人做這樣的事情趕上:

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的「參與方」數量必須與實際使用它的線程數完全相等。

+0

我試圖讓線程等待一定比例的完成進度,但這很困難,因爲那之後我不得不停止我的程序,一個for循環,然後再次啓動它,我認爲這是不可能的......在程序完成之前,我完全不在意100%掛起,但這些線程會在不同的時間完成。 – 2014-11-24 08:50:16

+0

好吧,我只是在這方面做了一個嘗試,我覺得我真的很接近。更新了我的機器人類代碼。 – 2014-11-24 09:14:49

+0

我結束了更新我的我和增量(我用for循環)在我的run()方法調用的參數;每次我打到一定的門檻,並打等待命令,等待其他人最終到達同樣的障礙。你描述它的方式是行不通的,因爲每當我打電話給進展的方法時,它就會完成我的整個循環。我會發布我自己的答案,我猜即使它現在沒有什麼區別。 – 2014-11-24 10:00:53

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: "); 
}