title: Enforce order in which jobs executed by ThreadPoolExecutor finish
body: <p>I have a bunch of demanding operations <strong>that can run in parallel but they have to finish in certain order</strong>. By finish I mean write the results to a file. Of course I could re-order the results when all jobs are finished but I'd like to avoid that (especially because the results might be too big to be kept in memory).</p>
  
  <p>I use a modified <code>ThreadPoolExecutor</code> to run the jobs in parallel that makes sure that only limited number of jobs is running at a time to reduce the memory consumption.</p>
  
  <p>My idea is that each job will have a reference to the previous one and before writing the results it will wait until the previous one is done (if necessary). It seems like a simple synchronization problem but as I'm not experienced in this kind of stuff I'd like to hear an opinion if it's actually going to work as intended. Also regarding the memory management. Once a job is finished, the garbage collector should be able to remove it from memory.</p>
  
  <pre><code>abstract public class WaitingJob extends Job {
  
      /** Job to wait for before we finish this job */
      protected WaitingJob previousJob;
  
      /** Job status */
      protected boolean finished = false;
  
      public WaitingJob(WaitingJob previousJob) {
          this.previousJob = previousJob;
      }
  
      @Override
      public void run() {
          // Perform the actual job (which might decide to wait for the previous one)
          runWithWaiting();
  
          // Wake up any job that's waiting for us.
          synchronized (this) {
              finished = true;
              notifyAll();
          }
  
          // Release memory (manually, to break the chain).
          previousJob = null;
      }
  
      /** If the previous job is not finished yet, let's wait for it. */
      protected void waitForPreviousJob() throws InterruptedException {
          if (previousJob != null) {
              synchronized (previousJob) {
                  while (!previousJob.finished) {
                      previousJob.wait();
                  }
              }
          }
      }
  
      /** Perform the job with the possibility to wait on the previous one. */
      protected abstract void runWithWaiting();
  }
  </code></pre>
  
  <p>Sample job:</p>
  
  <pre><code>class SampleJob extends WaitingJob {
      @Override
      protected void runWithWaiting() {
          try {
              Thread.sleep(1000);  // Do heavy work
              waitForPreviousJob();
              // Write down work
          } catch (InterruptedException e) {
          }
      }
  }
  </code></pre>
  
  <p>I run couple of tests on this and it seems to behave as it should but I'm not sure if there are any dangerous moments. </p>
  
  <p>Also, are there any existing better solutions?</p>