2017-05-16 43 views
0

所以我有一個非常大的項目,但最終將問題歸結爲以下情況。爲什麼我的循環只能在使用SOUT時繼續?

我有主類 「LoopTest」 和另一個階級 「RandomClassObject」

LoopTest:

public class LoopTest { 

static RandomClassObject rco; 
public static void main(String[] args) { 
    rco = new RandomClassObject(); 
    System.out.println("RCO has finished"); 
} 

}

RandomClassObject:

public class RandomClassObject { 

JFrame frame = new JFrame(); 
JButton button = new JButton("Click Me"); 
boolean created = false; 

public RandomClassObject() { 
    button.addActionListener(this::buttonActionPerformed); 
    frame.add(button); 
    frame.setVisible(true); 
    while (!created) { 
     //System.out.println("Done"); //This needs to be uncommented to work. 
    } 
    System.out.println("It was been Created"); 
} 

public void buttonActionPerformed(ActionEvent evt) { 
    created = true; 
} 

所以我想讓我的RandomClassObject等到按下按鈕。 我有一個布爾「創建」並有一個while循環循環,直到所述布爾值更改爲true。

當與SOUT「完成」運行註釋掉,我點擊按鈕,但從來沒有得到第二個SOUT「它已被創建」。

當SOUT「完成」取消註釋運行時,我收到垃圾郵件與「完成」的和一旦我點擊按鈕我收到SOUT「它已被創建」。

我需要幫助瞭解爲什麼我必須在我的循環中放入SOUT以便永久退出buttonClick。

對不起,如果這是一個明顯的錯誤,並感謝任何答覆!

回答

2

您有一個同步問題。按鈕點擊發生在事件線程中,並且您的循環(在主線程中運行)從未看到它所做的更新。因爲您不強制兩個線程之間的內存同步,機器可以自由地忽略更改。

System.out.println的調用具有強制內存同步的副作用,允許主線程查看事件線程所做的更改。

要解決此問題,請將created設爲AtomicBoolean或將​​關鍵字添加到您的complete方法中。

在任何情況下,循環都是不好的方法來實現這個結果。考慮從按鈕上的事件監聽器驅動你的完成邏輯。

你說你需要暫停你的主線程直到字符被創建。要做到這一點的方法之一是使用鎖:

public class Main { 
    public static void main(String[] args) throws InterruptedException { 
     CountDownLatch latch = new CountDownLatch(1); 

     JFrame frame = new JFrame("Test..."); 
     JButton button = new JButton("Click Me"); 
     button.addActionListener(e -> latch.countDown()); 
     frame.add(button); 
     frame.pack(); 
     frame.setVisible(true); 

     // Wait here for the click in the event thread 
     latch.await(); 

     System.out.println("Clicked!"); 

     frame.dispose(); 
    } 
} 

調用latch.await()將阻止你的主線程,直到您的活動線程釋放閂鎖與latch.countDown()

+0

謝謝@teppic!我的完整方法之前的synchronized關鍵字有所幫助。我知道你說使用按鈕的事件監聽器會更好,但我需要這個循環來暫停主程序繼續,直到對象RCO被點擊。 –

+1

有幾種方法可以做到這一點。我編輯了答案並添加了一條建議。 – teppic