title: "HandshakeCompleteNotify" thread causes program to stall
body: <p>So, I'm running into a strange issue and I'm really stuck.  I have a long winded process (loads 10 million + records into salesforce).  When I run this process everything goes well until the end.  </p>
  
  <p>At the end of this process, I wait for confirmation back from salesforce that all records have loaded successfully. </p>
  
  <p>Sometimes (not always but most of the time), the program just seems to stall.  If I pause the debugger, it doesn't pull up any code lines and I can't use the "step" functions.  While its stalling, a thread flashes faster than I can read what it says.  I managed to capture it by screen-shooting my desktop as fast as I could.</p>
  
  <p><img src="https://i.stack.imgur.com/sBNf3.png" alt="enter image description here"></p>
  
  <p>Any advice on how to trouble shoot this?  Insight to why this might be happening?  I'm a bit out of my comfort zone with this one.</p>
  
  <h2>Update</h2>
  
  <p>So it turns out, after a very long time it finally does return as expected.  It appears that the thread is doing some sort of work and but maybe isn't getting a fair share of the resources?  Still have no idea why it's happening.  Maybe it has something to do with a <strong>thread.sleep()</strong> call I'm making in a loop?</p>
  
  <p>This is basically the code in question.  It came from <a href="https://www.salesforce.com/us/developer/docs/api_asynch/" rel="nofollow noreferrer">this resource put out by salesforce</a>.</p>
  
  <pre><code>/**
   * Wait for a job to complete by polling the Bulk API.
   * 
   * @param connection
   *            BulkConnection used to check results.
   * @param job
   *            The job awaiting completion.
   * @param batchInfoList
   *            List of batches for this job.
   * @throws AsyncApiException
   */
  private void awaitCompletion(BulkConnection connection, JobInfo job,
        List&lt;BatchInfo&gt; batchInfoList)
          throws AsyncApiException {
      long sleepTime = 0L;
      Set&lt;String&gt; incomplete = new HashSet&lt;String&gt;();
      for (BatchInfo bi : batchInfoList) {
          incomplete.add(bi.getId());
      }
      while (!incomplete.isEmpty()) {
          try {
              Thread.sleep(sleepTime);
          } catch (InterruptedException e) {}
          System.out.println("Awaiting results..." + incomplete.size());
          sleepTime = 10000L;
          BatchInfo[] statusList =
            connection.getBatchInfoList(job.getId()).getBatchInfo();
          for (BatchInfo b : statusList) {
              if (b.getState() == BatchStateEnum.Completed
                || b.getState() == BatchStateEnum.Failed) {
                  if (incomplete.remove(b.getId())) {
                      System.out.println("BATCH STATUS:\n" + b);
                  }
              }
          }
      }
  }
  </code></pre>