Android Movie Class With AsyncTask
You could try to write your app in callback passing style. That means methods that take a while (e.g. methods for fetching data from the web) take a callback argument that contains the code that will run once the operation is finished.

This program uses two ExecutorServices. One processes everything in one single thread. The other one runs stuff in parallel. All the code you run with the parallel ExecutorService should never access any objects that are modified by the rest of the program unless you know how to do synchronization correctly. But you don't need any synchronization at all here. Just ensure all the code that modifies the state of your program runs only in the single threaded ExecutorService and everything will be fine.
You may notice that final is used a lot in this code. That's because variables that are implicitly passed to an anonymous class need to be final.

class Tools {
  public final static ExecutorService async = Executors.newSingleThreadExecutor();
  public final static ExecutorService parallel = Executors.newFixedThreadPool(8);

  public static void shutdown() {
    Tools.async.shutdown();
    Tools.parallel.shutdown();
  }

  public static void getImageFromUrl(final String urlString, final Async&lt;Bitmap&gt; async) {
    Tools.parallel.execute(new Runnable() {
      public void run() {
        try {
          System.out.println(Thread.currentThread() + " - Loading image: " + urlString);
          async.send(null);
          /*
          URL url = new URL(urlString);
          HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          connection.setDoInput(true);
          connection.connect();
          InputStream inputStream = connection.getInputStream();
          async.send(BitmapFactory.decodeStream(inputStream));
          */
        } catch(Exception e) {
          async.error(e);
        }
      }
    });
  }
}

abstract class Async&lt;T&gt; {
  abstract protected void accept(T t);
  public void send(final T t) {
    final Async&lt;T&gt; self = this;
    Tools.async.execute(new Runnable() {
      public void run() {
        self.accept(t);
      }
    });
  }

  public void error(Throwable err) {
    err.printStackTrace();
  }
}

class Ref&lt;T&gt; {
  private T value;
  public Ref(T value) {
    this.value = value;
  }
  public T get() {
    return value;
  }
  public void set(T value) {
    this.value = value;
  }
}

class Test {
  public static void main(String[] args) {
    Tools.async.execute(new Runnable() {
      public void run() {
        mainProgram();
      }
    });
  }

  private static void mainProgram() {
    final ArrayList&lt;Movie&gt; movies = new ArrayList&lt;&gt;();
    final Ref&lt;Integer&gt; numImages = new Ref&lt;&gt;(10);
    for(int i = 0; i &lt; 10; i++) {
      final int imageNr = i;
      Tools.getImageFromUrl("http://image-website/image" + i, new Async&lt;Bitmap&gt;() {
        public void accept(Bitmap image) {
          System.out.println(Thread.currentThread() + " - Creating movie object for image: " + imageNr);
          movies.add(new Movie("", "", "", "", "", 0, 0, 0, image));
          numImages.set(numImages.get() - 1);
          if(numImages.get() == 0) {
            allMoviesLoaded(movies);
          }
        }
      });
    }
  }

  private static void allMoviesLoaded(ArrayList&lt;Movie&gt; images) {
    System.out.println("All movies loaded");
    Tools.shutdown(); //ends the program
  }
}