• 12 hours
  • Hard

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 11/8/22

Integrate Basic Concurrency Techniques into Code

Evaluated skills

  • Integrate basic concurrency techniques into code

Description

This quiz will evaluate your understanding of how and when to use concurrency and parallelism in Java. You'll use threads, parallel streams, and Futures to count the number of letters in a list of planet names. Remember that you can use JShell if you want to try out examples.

Let's start with this list of planets created in JShell:

jshell> List<String> planets = List.of("mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", "neptune")
planets ==> [mercury, venus, earth, mars, jupiter, saturn, uranus, neptune]

 

  • Question 1

    Given the list of planets above, which of the following snippets of concurrent code will print "mars" to our screen?

    Careful, there are several correct answers.
    • Thread myThread = new Thread(()->{
      for (String planet : planets) {
      Thread planetThread = new Thread( () -> {
      if (planet.equals("Mars")) {
      System.out.println(planet);
      }
      });
      planetThread.start();
      }
      });
      myThread.start();

       

    • planets.parallelStream().filter(planet -> planet.equals("mars")).forEach(planet -> System.out.println(planet))
    • Future<String> f = Executors.newSingleThreadExecutor().submit(
      () -> {
      if (planets.contains("mars")){
      return "mars";
      }
      return null;
      });
      System.out.println(f.get());
    • FutureTask<String> findMars = new FutureTask<>(()->planets.get(planets.lastIndexOf("mars")));
      Thread marsFinder = new Thread(findMars);
      System.out.println( findMarsTask.get() );

       

  • Question 2

    Look at this snippet of code:

    FutureTask<String> findMars = new FutureTask<>(()->planets.get(planets.lastIndexOf("mars")));
    Thread marsFinder = new Thread(findMars);

    What will be returned by calling  marsFinder.getState()  immediately after this line?

    • NEW

    • RUNNABLE

    • WAITING

    • BLOCKED

    • TERMINATED

  • Question 3

     You start working with a team interested in different sizes of planets, as measured in Earth Masses. They model this in the following object:

    class Planet {
    // For prototyping. Don't break encapsulation in real code.
    public String name;
    public Double earthMasses;
    public Planet(String name, Double earthMasses) {
    this.name = name;
    this.earthMasses = earthMasses;
    }
    }

    To simulate a large list of planets which includes exotic planet from outside our solar system, you create the following class that can make a list of 2000 fake planets:

    public class FakePlanetListFactory {
    // make a list of fake planets
    public static List<Planet> make() {
    List<Planet> planets = IntStream.range(0,2000).
    // Create "planet:n" with a random earth mass
    mapToObj( n -> new Planet("planet:" + n, Math.random() ) ).
    // Create a list with a mutable reduction
    collect(Collectors.toList());
    return planets;
    }
    }

    Look at the following piece of code used to create an average from this new list of planets.

    public class PlanetAverager {
    private static Double subTotal;
    private static List<Planet> planets = FakePlanetListFactory.make();
    private static ExecutorService es = Executors.newCachedThreadPool();
    public static void main(String[] args) throws Exception {
    // Set subtotal to 0
    subTotal = 0.0;
    // Split the list in 2
    Integer midPoint = planets.size() / 2;
    // Sum up Earth masses on the left half of the list
    ExecutorService es = Executors.newCachedThreadPool();
    Future leftSum = addEarthMasses(planets.subList(0, midPoint));
    // Sum up Earth masses on the right half of the list
    Future rightSum = addEarthMasses(planets.subList(midPoint, planets.size()));
    // Allow Futures to finish
    leftSum.get();
    rightSum.get();
    Double average = subTotal / planets.size();
    System.out.println(average);
    }
    private static Future addEarthMasses(List<Planet> planetSubList) {
    return es.submit(()->
    planetSubList.stream().
    mapToDouble(planet -> planet.earthMasses).
    forEach(n -> subTotal+=n)
    );
    }
    }

    Which of the following statements are true about the shared mutable subTotal? Feel free to check the Java docs.

    Careful, there are several correct answers.
    • This code is thread-safe because you call  .get()  on each Future sequentially.

    • You can make this code thread-safe by replacing  static Double subTotal  with an  AtomicDouble  and then use addAndGet() to add each planet's earth mass from your threads.

    • This code can be thread-safe by putting your  subTotal  in an  AtomicReference<Double>  and incrementing and fetching its value using atomic methods such as  updateAndGet().

    • This code can be made thread-safe by removing subTotal and modifying  addAtomicMasses(List<Planet> subList)  to return a  Future<Double>. The method can  submit()  a Callable, which returns the sum of the subList. You should then assign those values to final variables which you add up when you need them.

    • The code is thread-safe as  subTotal += n  uses the atomic += operator to only allow one thread at a time to modify  subTotal .

Ever considered an OpenClassrooms diploma?
  • Up to 100% of your training program funded
  • Flexible start date
  • Career-focused projects
  • Individual mentoring
Find the training program and funding option that suits you best