Difference between revisions of "Understanding Fork Join"

From CSE231 Wiki
Jump to navigation Jump to search
(Created page with "== Overview == This page will walk you through reading documentation and understanding what the functions do in a practical manner. == Fork == <p>When we look at the docs, we...")
 
Line 3: Line 3:
  
 
== Fork ==
 
== Fork ==
 +
=== Reading the Documentation ===
 
<p>When we look at the docs, we are greeted with the following:</p>
 
<p>When we look at the docs, we are greeted with the following:</p>
[[File:Fork docs.png]]
+
 
 +
<p><code>public static <T> [https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/concurrent/Future.html Future<T>] [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse231/current/apidocs/fj/FJ.html#fork(fj.api.TaskSupplier) fork]([https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse231/current/apidocs/fj/FJ.html#fork(fj.api.TaskSupplier) TaskSupplier<T>] task)</code></p>
 +
 
 +
<p>What does this mean? Let's break it down</p>
 +
 
 +
==== Static ====
 
<p><code>static</code> means that the function is related to the class, <code>FJ</code> as opposed to a specific instance of that class. This means that we can call <code>FJ.fork</code> directly, we don't need to create an instance of that class to do so. In our code, we typically just write <code>fork</code> because Professor Cosgrove has imported the appropriate dependencies for you!</p>
 
<p><code>static</code> means that the function is related to the class, <code>FJ</code> as opposed to a specific instance of that class. This means that we can call <code>FJ.fork</code> directly, we don't need to create an instance of that class to do so. In our code, we typically just write <code>fork</code> because Professor Cosgrove has imported the appropriate dependencies for you!</p>
 +
 +
==== Lambda Functions ====
 +
<p>We see that <code>fork</code> takes in one parameter of type <code>TaskSupplier<T></code>. If we follow the link, we see that a <code>TaskSupplier<T></code> is just a single function, which has a return type <code>T</code> and can throw <code>InterruptedException</code> and <code>ExecutionException</code>.</p>
 +
 +
<p><code>T [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse231/current/apidocs/fj/api/TaskSupplier.html#get() get()] throws [https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/InterruptedException.html InterruptedException],[https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/concurrent/ExecutionException.html ExecutionException]</code></p>
 +
 +
<p>Thus, any function that takes in no parameters and returns anything qualifies as a <code>TaskSupplier<T></code>. In code for this course, you will often see code such as:</p>
 +
{{CollapsibleCode|Lambda function &nbsp;|<pre>public int count(/* parameters */) {
 +
    Future<Integer> firstHalfFuture = fork(() -> {
 +
        /* Parallel task */
 +
    });
 +
    /* Main task */
 +
    int firstHalf = join(firstHalfFuture);
 +
    /* more code */
 +
}</pre>}}
 +
<p>This is the same as:</p>
 +
{{CollapsibleCode|Explicit function &nbsp;|<pre>public int myFunc() {
 +
    /* Parallel task */
 +
}
 +
public int count(/* parameters */) {
 +
    Future<Integer> firstHalfFuture = fork(() -> myFunc());
 +
    /* Main task */
 +
    int firstHalf = join(firstHalfFuture);
 +
    /* more code */
 +
}</pre>}}
 +
<p>In the first case, we defined the function inline at the <code>fork</code> method call, while the second case is more akin to what you may be used to</p>
 +
==== Generics ====
 +
<p>You may have the question, what is a value of type <code>T</code>? <code><T></code> means that we have a generic type called <code>T</code>. <code>T</code> isn't any one type in particular, but instead is just a guarantee that in the following code, whenever we see <code>T</code>, it is referring to the same type. An example you may be more familiar with is the <code>ArrayList<E></code> class. If we look at the [https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html documentation] for <code>ArrayList<E></code>, we see, among other things:</p>
 +
 +
<p><code>public class [https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html ArrayList<E>]</code></p>
 +
<p><code>public boolean [https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#add-E- add](E e)</code></p>
 +
<p><code>public E [https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#get-int- get](int index)</code></p>
 +
 +
<p>In the case of <code>ArrayList<E></code>, <code>E</code> is the name of the generic type. And thus, everywhere we see <code>E</code>, it is the same type <code>E</code> as was supplied to the class constructor. That is why when you create an <code>ArrayList<Integer></code>, you are able to use it for <code>Integer</code>, but not some other type such as <code>String</code>. Then, when you create an <code>ArrayList<String></code>, you are able to use it for <code>String</code>, but not other types such as <code>Integer</code>.</p>
 +
<p>Coming back to the <code>fork</code> function, we next see that the return type is <code>Future<T></code>. We can follow the link to the java documentation for <code>Future</code> to see that when we call <code>Future.get()</code>, it will return a value of type <code>T</code></p>
 +
 +
==== Practical Explanation ====
 +
<p>So putting all of this together, the <code>fork</code> function is a static function that is tied to the <code>FJ</code> class, and not any specific instance of that class. It takes in a function that returns any type <code>T</code>, and returns a <code>Future<T></code> object, which will return a value of that same type <code>T</code> when the <code>get</code> function is called on it. The function that is passed into the <code>fork</code> function is run in parallel to the main process.</p>

Revision as of 05:18, 10 February 2023

Overview

This page will walk you through reading documentation and understanding what the functions do in a practical manner.

Fork

Reading the Documentation

When we look at the docs, we are greeted with the following:

public static <T> Future<T> fork(TaskSupplier<T> task)

What does this mean? Let's break it down

Static

static means that the function is related to the class, FJ as opposed to a specific instance of that class. This means that we can call FJ.fork directly, we don't need to create an instance of that class to do so. In our code, we typically just write fork because Professor Cosgrove has imported the appropriate dependencies for you!

Lambda Functions

We see that fork takes in one parameter of type TaskSupplier<T>. If we follow the link, we see that a TaskSupplier<T> is just a single function, which has a return type T and can throw InterruptedException and ExecutionException.

T get() throws InterruptedException,ExecutionException

Thus, any function that takes in no parameters and returns anything qualifies as a TaskSupplier<T>. In code for this course, you will often see code such as:

Lambda function    
public int count(/* parameters */) {
    Future<Integer> firstHalfFuture = fork(() -> {
        /* Parallel task */
    });
    /* Main task */
    int firstHalf = join(firstHalfFuture);
    /* more code */
}

This is the same as:

Explicit function    
public int myFunc() {
    /* Parallel task */
}
public int count(/* parameters */) {
    Future<Integer> firstHalfFuture = fork(() -> myFunc());
    /* Main task */
    int firstHalf = join(firstHalfFuture);
    /* more code */
}

In the first case, we defined the function inline at the fork method call, while the second case is more akin to what you may be used to

Generics

You may have the question, what is a value of type T? <T> means that we have a generic type called T. T isn't any one type in particular, but instead is just a guarantee that in the following code, whenever we see T, it is referring to the same type. An example you may be more familiar with is the ArrayList<E> class. If we look at the documentation for ArrayList<E>, we see, among other things:

public class ArrayList<E>

public boolean add(E e)

public E get(int index)

In the case of ArrayList<E>, E is the name of the generic type. And thus, everywhere we see E, it is the same type E as was supplied to the class constructor. That is why when you create an ArrayList<Integer>, you are able to use it for Integer, but not some other type such as String. Then, when you create an ArrayList<String>, you are able to use it for String, but not other types such as Integer.

Coming back to the fork function, we next see that the return type is Future<T>. We can follow the link to the java documentation for Future to see that when we call Future.get(), it will return a value of type T

Practical Explanation

So putting all of this together, the fork function is a static function that is tied to the FJ class, and not any specific instance of that class. It takes in a function that returns any type T, and returns a Future<T> object, which will return a value of that same type T when the get function is called on it. The function that is passed into the fork function is run in parallel to the main process.