2010-05-30 30 views
0

我已經參考this previous question以及其他來源,但無法使CountDownLatch正常工作。用於等待JFrame處置的Java CountDownLatch

背景:mainFrame創建一個名爲dataEntryFrame的新框架。當dataEntryFrame「Submit」按鈕被點擊時,記錄添加到數據庫和dataEntryFrame處理。此時,mainFrame應清除並重新加載一個顯示所有記錄的jList。

問題:當dataEntryFrame加載時,java凍結,dataEntryFrame組件永不加載。 我無法超越這部分... 然後,在DataEntryFrame中,CountDownLatch應該只在遞交按鈕被點擊後成功遞減,成功地將一條記錄添加到數據庫表中並處理它自己。或者,當用戶點擊取消...

代碼:從大型機

clearList(); 
CountDownLatch dataEntryDone = new CountDownLatch(1); 
DataEntryFrame f = new DataEntryFrame(dataEntryDone); 
Thread newThread = new Thread(f); 
newThread.start(); 
dataEntryDone.await(); 
reLoadList(); 

代碼:從DataEntryFrame

public void run(){ 
initComponents(); 
loadOtherData(); 
this.setVisible(true); 
} 
void submit(){ 
addRecord(); 
this.dispose() 
dataEntryDone.countDown(); 
} 
+2

沒有足夠的信息來告訴是肯定的,但它看起來像大型機事件調度線程鎖定時等待閂鎖。同時,DataEntryFrame代碼在Swing事件派發線程之外執行,這對於Swing/AWT對象是不正確的。提供更多的代碼會很有用。 – 2010-05-30 19:14:41

回答

2

使用的dataEntryFrame一個新的線程和阻塞主機作對Swing線程模型。在Swing中,所有對Swing中UI組件的調用都必須在Event Dispatch Thread上進行。爲了驗證這是在開發過程中發生的,你可以安裝一個重繪管理器,如果它檢測到UI組件正在被另一個線程使用,就會拋出一個異常。參見FEST - Testing that access to GUI components is done in the EDT。爲了確保EDT上發生某些事情,您可以使用SwingUtilities.invokeAndWait/invokeLater。

您的主框架沒有(也不應該)不得不等待數據輸入框而不是CountDownLatch讓您的數據輸入框在完成時觸發一個事件給MainFrame,以便MainFrame可以採取適當的行動,例如刷新列表。

只是爲了將水進一步渾濁,將數據保存到數據庫並獲取列表的數據理想情況下應在事件分派線程上完成而不是。而應使用SwingWorker在他們自己的線程中執行這些操作。然而,與所有UI組件都必須從EDT訪問的規則不同,後臺處理的規則並不困難和快速,但建議保持響應式用戶界面 - 如果數據傳入/傳出數據庫需要很長時間並且它在UI線程(EDT)上完成,然後UI將凍結。

+0

感謝您的幫助詞語,mdma和Noel。在諾埃爾請求更多代碼之後,我開始關注EDT和Swing Worker。 SwingWorker看起來像是要走的路線和CountDownLatch。你說得對,數據庫查詢可以類似地完成......我現在看不到性能受到影響,但規模較大,我相信會發生這種情況。 我也發現了這個,這可能很有用:http://java.sun.com/docs/books/tutorial/uiswing/concurrency/dispatch.html javax.swing.SwingUtilities。isEventDispatchThread() – Brian 2010-05-31 12:15:55

+0

現在我想到了,這是一個現在知道我不知道的情況......所以再次感謝。 – Brian 2010-05-31 12:17:55

+0

歡迎您。您錯過了這一點並不奇怪 - 首先,java獲得了一個多線程GUI工具包 - AWT,然後在沒有多線程支持的情況下,它將擴展到Swing中。 – mdma 2010-05-31 13:41:22