2014-06-22 48 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,并且其中一个线程正在从结构上修改列表。

相关问题