2014-06-22 114 views
1

有兩個線程A和B.一直寫入一個ArrayList,B一直在讀取它。以下代碼用於讀取ArrayList並屬於線程B.在讀取ArrayList的最後一個索引時返回null

此代碼的問題是,有時兩個IF語句都變爲true,這應該是不可能的。第一個IF是爲了確保列表不會超出其大小。 第二個IF不是實際代碼的一部分。我已將其僅用於驗證目的。正如你在下面的輸出中看到的,列表的大小大於writeNext變量,我不明白爲什麼這會返回null。是的,如果我在第一次IF之後放置打印語句或非常小的延遲,則一切正常。請記住只有一個線程寫入ArrayList,所以問題不應與同步有關。

public void run() {// thread B 

public class WriteTicksToFile implements Runnable, Serializable { 

    int writeNext = 0; 

    @Override 
    public void run() { 

     while (true) { 

      // read till writeNext is equal to ArrayList.size()-1 i.e. the last index 
      if (writeNext < TickData.getCompleteTickList().size()) { 

       // System.out.println(TickData.getCompleteTickList().size()+" "+writeNext); 
       if (TickData.getCompleteTickList().get(writeNext) == null) { 

        System.out.println("ListSize: " + TickData.getCompleteTickList().size() + " " + "[email protected]: " + writeNext); 

       }// if ends 

       // write element to file. 
       writeTick(TickData.getCompleteTickList().get(writeNext)); 
       writeNext++; 
      }// if ends 
     }// while ends 
    } 
} 

輸出

Number of symbols found: 19 
Market Opening time: 81500 
Market Closing time: 235900 
Current Time: 203931 
Waiting for market to open... 
Market Opened @ 203931 
ListSize: 15876 [email protected]: 15875 
ListSize: 15877 [email protected]: 15876 
+0

如果單獨的線程寫入列表中,那麼當讀線程在兩個if語句之間時,它可能只是寫入正確的線程。所以我猜想它實際上與同步相關。 –

+0

@IngoBürk同意;我沒有看到確保獨佔訪問列表的任何機制。 –

+0

向我們展示線程A使用的代碼。 – fajarkoe

回答

4

請記住,只有一個線程寫入 ArrayList中,這樣的問題不應該與同步。

這是不正確的,根據的Javadoc ArrayList

注意,此實現不是同步的。如果多個線程 同時訪問ArrayList實例,並且至少有一個線程在結構上修改列表,則必須在外部同步 。

您有多個線程同時訪問ArrayList,並且其中一個線程正在從結構上修改列表。

相關問題