2013-01-18 67 views
2

在我的j2me JAVA應用程序中有一個線程,它初始化一個對象,我必須通過返回它的值來獲取其他類。返回在線程中更改/初始化的值

在我的主要類中,我之後調用線程,我必須得到在Thread中被更改的值,但問題是線程完成之前調用該函數並返回null並且程序沒有更進一步處理。

我所做的就是將返回的值等待,直到布爾狀態在線程內沒有變爲真,但是因爲while循環它掛在那裏並且不會回來。

我發佈了下面的代碼讓我知道最好的解決方案,請記住這個代碼是在J2ME(Java)中,即使對於線程也具有有限的功能,因此不建議像Latch或BackgroundWorker這樣的方法,因爲它不起作用這裏。

這裏是線程等功能,HSA返回值

public synchronized void run() { 
    try { 
     contacts.removeAllElements(); 
     pim = PIM.getInstance(); 
     String lists[] = pim.listPIMLists(PIM.CONTACT_LIST); 
     for (int i = 0; i < lists.length; i++) { 
      //code for custom backup operation 
      if (customCode == 1 && i == 0) { 
       continue; 
      } else if (customCode == 0 && i > 0) { 
       continue; 
      } 
      clist = (ContactList) pim.openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE, lists[i]); 
      Enumeration cenum = clist.items(); 
      while (cenum.hasMoreElements()) { 
       Contact c = (Contact) cenum.nextElement(); 
       ContactDTO contact = new ContactDTO(); 
       parseContactInfo(c, contact); 
       contacts.addElement(contact); 
      } 
      clist.close(); 
     } 
     readComplete = true; 
    } catch (Exception e) { 
    } 
} 

//Return contacts loaded into vector list 
public ContactVector getLoadedContacts() { 
    while(!readComplete){ 
     Thread.sleep(100); 
     } 
    return contacts; 
} 

這是從哪兒我必須把這個

public ContactVector getContactVector() { 
    DeviceContactRetriever dcr = new DeviceContactRetriever(this, language); 
    dcr.start(); 
    ContactVector vector = dcr.getLoadedContacts();  //problem line* 
    return vector; 
} 

所以*問題行主類在完成之前返回對象,因此它是空的。

+0

'readComplete' - 它被聲明爲'volatile'嗎?因爲如果沒有,你可能會陷入困境 – gnat

回答

-1

您的問題是代碼不同步。

您需要使用方法wait()notify(),約象下面這樣:

public synchronized void run() { 
    try { 
     contacts.removeAllElements(); 
     //... 
     readComplete = true; 
     this.notify(); 
    } catch (Exception e) { 
    } 
} 

//Return contacts loaded into vector list 
public synchronized // <-- note sync'd here 
     ContactVector getLoadedContacts() { 
    while(!readComplete){ 
     this.wait(); 
     } 
    return contacts; 
} 

這是很基本的東西,考慮併發學習Java教程。

如果可能的話,請查看Java 5以前的Java版本的教程,否則將解釋您可以在Java ME中使用的內容(僅限於目前的Java 1.3)將與現代功能「混合在一起」,從而更難以學習與你相關的部分。

奏效這樣對我的一個實例教程是由Jacob Jenkov here,從章「簡介...」到「溜條件」的包容性。注意其他章節(「Locks」和其他章節)也不錯,但是這些章節嚴重依賴自Java 5以後引入的功能(JSR 133/166 - JMM和併發實用程序)。


夫婦對與上面解釋的錯誤無關的代碼迷惑。

  1. 因爲你的代碼是相當複雜的,考慮增加日誌消息,使其更容易調試(as explained eg here)。特別是我會強烈在catch塊中記錄類似異常的東西(如果你感興趣的話,搜索網絡中的_Java不會吞下異常),以及lists是否爲空,如果不是,它的大小以及clist,cenumc是否爲空。

  2. 考慮讓代碼更容易閱讀和提取到單獨的方法(如explained here)代碼是內forwhile循環的片段修改。

  3. 請注意,由於getContactVector()中的代碼可能需要很長時間才能運行,因此最好避免從UI線程調用它。如果您有興趣瞭解爲什麼以及如何正確執行此操作,請參閱lcdui tag wiki中提及的教程「網絡,用戶體驗和線程」。

+0

感謝您的回覆和建議,但返回對象的代碼仍然掛起:( – Saqib

+0

@Saqib測試以找出它掛起的位置:1)簡化'run'中的代碼,以便1) try-catch只打印一些東西(我假設你在模擬器上測試);如果這樣做的話,那麼2)做for-loop只打印一些東西,縮小它在內部「摺疊」代碼,而只是打印一些東西等。添加更多的日誌記錄來追蹤東西等 – gnat

+1

它在模擬器以及在設備上它仍然顯示我以前遇到的問題,我發現這是因爲移動設備或固件。所以考慮你的答案是爲了我問的目的。謝謝 – Saqib