title: Java multithreaded parser
body: <p>I am writing a multithreaded parser.
  Parser class is as follows.</p>
  
  <pre><code>public class Parser extends HTMLEditorKit.ParserCallback implements Runnable {
  
      private static List&lt;Station&gt; itemList = Collections.synchronizedList(new ArrayList&lt;Item&gt;());
      private boolean h2Tag = false;
      private int count;
      private static int threadCount = 0;
  
      public static List&lt;Item&gt; parse() {
          for (int i = 1; i &lt;= 1000; i++) { //1000 of the same type of pages that need to parse
  
              while (threadCount == 20) { //limit the number of simultaneous threads
                  try {
                      Thread.sleep(50);
                  } catch (InterruptedException ex) {
                      ex.printStackTrace();
                  }
              }
  
              Thread thread = new Thread(new Parser());
              thread.setName(Integer.toString(i));
              threadCount++; //increase the number of working threads
              thread.start();            
          }
  
          return itemList;
      }
  
      public void run() {
          //Here is a piece of code responsible for creating links based on
          //the thread name and passed as a parameter remained i,
          //connection, start parsing, etc.        
          //In general, nothing special. Therefore, I won't paste it here.
  
          threadCount--; //reduce the number of running threads when current stops
      }
  
      private static void addItem(Item item) {
          itenList.add(item);
      }
  
      //This method retrieves the necessary information after the H2 tag is detected
      @Override
      public void handleText(char[] data, int pos) {
          if (h2Tag) {
              String itemName = new String(data).trim();
  
          //Item - the item on which we receive information from a Web page
          Item item = new Item();
          item.setName(itemName);
          item.setId(count);
          addItem(item);
  
          //Display information about an item in the console
          System.out.println(count + " = " + itemName); 
          }
      }
  
      @Override
      public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
          if (HTML.Tag.H2 == t) {
              h2Tag = true;
          }
      }
  
      @Override
      public void handleEndTag(HTML.Tag t, int pos) {
          if (HTML.Tag.H2 == t) {
              h2Tag = false;
          }
      }
  }
  </code></pre>
  
  <p>From another class parser runs as follows:</p>
  
  <pre><code>List&lt;Item&gt; list = Parser.parse();
  </code></pre>
  
  <p>All is good, but there is a problem. At the end of parsing in the final list "List itemList" contains 980 elements onto, instead of 1000. But in the console there is all of 1000 elements (items). That is, some threads for some reason did not call in the handleText method the addItem method.</p>
  
  <p>I already tried to change the type of itemList to ArrayList, CopyOnWriteArrayList, Vector. Makes the method addItem synchronized, changed its call on the synchronized block. All this only changes the number of elements a little, but the final thousand can not be obtained.</p>
  
  <p>I also tried to parse a smaller number of pages (ten). As the result the list is empty, but in the console all 10.</p>
  
  <p>If I remove multi-threading, then everything works fine, but, of course, slowly. That's not good.</p>
  
  <p>If decrease the number of concurrent threads, the number of items in the list is close to the desired 1000, if increase - a little distanced from 1000. That is, I think, there is a struggle for the ability to record to the list. But then why are synchronization not working?</p>
  
  <p>What's the problem?</p>