Fork Join in Java
Multithreaded processors are being introduced in new computer systems today. The operation is faster due to multicore CPUs. Therefore, it becomes essential for a programmer to leverage multithreaded processors effectively in order to produce the output in a shorter amount of time.
Definition
Java uses fork/join to effectively utilize the cores, the portion of the CPU that processes instructions. A larger work is divided into smaller units of work using the fork/join tool. Then, the cores are divided up among these sub-tasks. The ultimate result is then produced by combining the outcomes of these smaller tasks. The divide-and-conquer method is imitated by breaking a task into smaller pieces and uniting the results. The process is probably split by the fork, and the task's results are merged together by the join to produce the outcome.
Importance
It is important to note that the many threads involved in completing the sub-tasks never remain idle. They actually employ the work-stealing algorithm, in which an inactive thread appropriates the workload from active threads.
It's crucial to keep in mind that one shouldn't arbitrarily divide a problem into smaller ones. There are costs involved in breaking a problem into smaller ones. One shouldn't split a problem into smaller ones if doing so results in more overhead and time being spent than just tackling the main issue. Threshold is the upper limit at which it is logically possible to divide a problem into subproblems.
ForkJoinPool Class in Java
The ForkJoinPool class serves as the foundation of the fork/join infrastructure. The ExecutorService interface is implemented by the ForkJoinPool class. It also performs the work-stealing mechanism and inherits the AbstractExecutorService class.
ForkJoinPool Class Methods
- public int getParallelism(): This method returns the pool's parallelism threshold.
- public boolean isShutdown(): This method returns true if indeed the pool calling it has been closed; or else, it gets complicated.
- public boolean isQuiescent(): This method returns true when all of the service threads in the pool are still idle; or else, it returns false.
- public boolean hasQueuedSubmissions(): The method returns true whether any task that was added to the pool still has not initiated to be executed; or else, it returns false.
- public int getPoolSize(): Indicates the absolute amount of service threads that already have started running but haven't finished.
- public long getStealCount(): The method gives back the overall amount of jobs which have been taken from the other service thread.
- public boolean isTerminating(): This method returns true if the ending procedure has begun but has not been completely finished; or else, it returns false.
- public int getActiveThreadCount(): The method returns the total amount of active threads that are carrying out their own tasks or robbing them from these other threads.
- public long getQueuedTaskCount(): This method gives back the overall amount of tasks that have been added to the worker threads' pools.
- public ForkJoinTask<?> submit(Runnable task): This method submits a Precompiled task for implementation and returns a Prospect that describes the task.
- public List<Runnable> shutdownNow(): The procedure tries to deny all subsequent tasks and halt or abort all current tasks.
Implementation of the Fork/Join
The ForkJoinClass can be built using two different methods.
- By using the constructor of the class
- ForkJoinPool(): It is the ForkJoinPool class's standard function Object() { [native code] }. A standard pool is made. The maximum number of processing units in the system is supported by the produced pool's duality. The ForkJoinPool class was created using this function Object().
- ForkJoinPool(int p): A pool with specialised parallelism is also created using this parameterized function Object() . The value of p must be a positive integer (more than 0) and cannot be greater than the system's total number of processors.
- By commonpool() method: A ForkJoinPool instance could also be made using the static method commonPool() of a ForkJoinPool class.
Demo12.java
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class SearchWork extends RecursiveTask<Integer>
{
int arr[];
int k, l;
int searchEle;
public SearchWork(int arr[], int s, int e, int searchEle)
{
this.arr = arr;
this.k = k;
this.l = l;
this.searchEle = searchEle;
}
@Override
protected Integer compute()
{
return countFreq();
}
private Integer countFreq()
{
int z = 0;
for (int j = k; j <= l; j++)
{
if (arr[j] == searchEle)
{
z = z + 1;
}
}
return z;
}
}
public class Demo12
{
public static void main(String argvs[])
{
int arr[] = { 22, 32, 61, 22, 49, 22, 16, 71,22, 94, 10, 90, 12, 22, 78, 98, 88, 99 };
int searchEle = 22;
int k = 0;
int l = arr.length - 1;
ForkJoinPool f = ForkJoinPool.commonPool();
SearchWork s = new SearchWork(arr, s, e, searchEle);
int freq = fjp.invoke(sw);
System.out.println("The number " + searchEle + " is found " + freq + " times. ");
}
}
Output
The number 22 is found 6 times.