I made a class to perform tasks concurrently and have implemented it. From appearances and testing, everything seems to work. How can I improve this? I understand this is somewhat a broad question, so please let me know how I should narrow it down.Here is the pseudocode:The general idea is a single Starter spawns multiple TaskWorker to do the work. I want to start the loading process fairly early on and then block EDT until the completion of all TaskWorker.class ImproveMe {  private AtomicInteger incompleteTasksCount = new AtomicInteger( -1 );  /* SwingWorker has a limitation of 10 */  private static final int MAX_CONCURRENT_THREAD = 20;  private static ExecutorService threadPool = Executors.newFixedThreadPool( MAX_CONCURRENT_THREAD );  /* This just starts multiple TaskWorker */  class Starter extends SwingWorker {    Object doInBackground() {      incompleteTasksCount.getAndSet( -1 );      Tasks[] taskList = getTasks();      for ( Task task : taskList ) {        /* Track incomplete tasks */        if ( incompleteTasksCount.compareAndSet( -1, 1 ) {          incompleteTasksCount.incrementAndget();        }        threadPool.submit( new TaskWorker( task ) );      }      threadPool.shutdown();    }  }  /* Performs the actual work -- I don't care about the results since it will be cached elsewhere */  class TaskWorker implements Runnable {    Task t;    TaskWorker( Task t ) {      this.t = t;    }    void run() {      if ( t != null ) {        do stuff with 't'      }      synchronized( incompleteTasksCount ) {        if ( incompleteTasksCount.decrementAndGet() == 0 ) {          /* everything is done! */          incompleteTasksCount.notifyAll();        }      }    }  }  /* User will call this to start the loading */  public void startLoading() {    if ( !threadPool.isShutdown() ) {      Starter s = new Starter();      s.execute();    }  }  /* User will call this to ensure that everything has complete before continuing */  public void blockUntilDone() {    boolean cont = true;    if ( incompleteTasksCount.get() == 0 || threadPool.isTerminated() ) {      return;    } else if ( incompleteTasksCount.get() == -1 ) {      /* not loaded/started */      return;    }    while ( cont ) {      synchronized( incompleteTasksCount ) {        try {          incompleteTasksCount.wait();        } catch ( InterruptedException e ) {          e.printStackTrace();          cont = false;        } finally {          if ( incompleteTasksCount.get() == 0 ) {            cont = false;          }        }      }    }  }}In reality, TaskWorker calls PrintService.getSupportedAttributeValues(..) because of the numerous printers and Java caches that so any future calls will return fairly quickly as compared to the first time (some of the network printers took 40+ seconds). I call ImproveMe.startLoading() somewhere fairly early in my program then before the actual program starts (e.g. GUI is shown), I use ImproveMe.blockUntilDone() to ensure everything is loaded.I was suggested to post here from StackOverflow.
Improve my threading in Java
java