- 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 anAtomicDouble
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 anAtomicReference<Double>
and incrementing and fetching its value using atomic methods such asupdateAndGet()
.This code can be made thread-safe by removing subTotal and modifying
addAtomicMasses(List<Planet> subList)
to return aFuture<Double>
. The method cansubmit()
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 modifysubTotal
.
- Up to 100% of your training program funded
- Flexible start date
- Career-focused projects
- Individual mentoring