In Java7, JDK provides a very powerful framework for multithreaded development, the Fork/join framework. This is for the original executors more
Furthermore, a work-stealing strategy in parallel partition calculation is added on the original basis, which means. When a thread is waiting for him to create the
When a child thread is running, the current thread, if it completes its own task, looks for tasks that have not been run and runs them, and that is
Executors this way the biggest difference, more efficient use of the resources and functions of the thread. Therefore, it is highly recommended to use the Fork/join framework.
Let's use an example to illustrate how this framework is used, primarily by creating a list of 10,000 resources to modify his content.
Package com.bird.concursey.charpet8;
/**
* Store the name and price of a product
* @author Bird October 7, 2014 PM 11:23:14/Public
class Product {
private String name;
private double price;
Public String GetName () {return
name;
}
public void SetName (String name) {
this.name = name;
}
Public double GetPrice () {return price
;
}
public void Setprice (double price) {
This.price = Price;
}
}
Package com.bird.concursey.charpet8;
Import java.util.ArrayList;
Import java.util.List;
/**
* Generate a list of random products
* @author Bird
* October 7, 2014 PM 11:24:47/Public
class Produc Tlistgenerator {public
list<product> generate (int size) {
list<product> List = new arraylist< Product> ();
for (int i = 0; i < size; i++) {
Product Product = new product ();
Product.setname ("Product" + i);
Product.setprice (ten);
List.add (product);
}
return list;
}
Package com.bird.concursey.charpet8;
Import java.util.List;
Import Java.util.concurrent.ForkJoinPool;
Import java.util.concurrent.RecursiveAction;
Import Java.util.concurrent.TimeUnit;
public class Task extends Recursiveaction {private static final long serialversionuid = 1L;
These attributes would determine the block of all products this task has to//process.
Private list<product> Products;
private int-I;
private int last;
Store the increment of the price of the products private double increment;
Public Task (list<product> products, int A, last, double increment) {super ();
This.products = Products;
This.first = A;
This.last = Last;
This.increment = increment; }/** * If The difference between the last and a attributes is greater than * or equal to, create two new Tas K objects, one to process the "half of the" and "the other" to "process" second half and execute * them in Forkjoinpool using the InvokealL () method.
* * @Override protected void compute () {if (Last-first <) {updateprices ();
else {int middle = (i + last)/2;
System.out.printf ("Task:pending tasks:%s\n", Getqueuedtaskcount ());
Task T1 = new Task (products, middle + 1, increment);
Task t2 = new Task (products, middle + 1, last, increment);
InvokeAll (t1, T2);
} private void UpdatePrices () {for (int i = a < last; i++) {Product Product = Products.get (i);
Product.setprice (Product.getprice () * (1 + increment));
} public static void Main (string[] args) {productlistgenerator productlistgenerator = new Productlistgenerator ();
List<product> products = Productlistgenerator.generate (10000);
Task task = new Task (products, 0, products.size (), 0.2);
Forkjoinpool pool = new Forkjoinpool ();
Pool.execute (Task);
do {System.out.printf ("Main:thread Count:%d\n", Pool.getactivethreadcount ()); System.out.printf ("Main:thread Steal:%d\n ", Pool.getstealcount ());
System.out.printf ("Main:parallelism:%d\n", pool.getparallelism ());
try {TimeUnit.MILLISECONDS.sleep (5);
catch (Interruptedexception e) {e.printstacktrace ();
} while (!task.isdone ());
Pool.shutdown ();
if (task.iscompletednormally ()) {System.out.printf ("main:the process has completed normally.\n"); for (product product:products) {if (Product.getprice ()!=) {System.out.printf ("Product%s:%f\n", Produc
T.getname (), Product.getprice ());
} System.out.println ("Main:end of the program.\n");
}
}
In this example, you have created a Forkjoinpool object and a subclass of the
Forkjointask class that's you execute in the pool. To create the Forkjoinpool object,
You have used the constructor without arguments and so it'll be executed with its default
Configuration. It creates a pool with a number of threads equal to the number of processors
of the computer. When the Forkjoinpool object is created, those threads are created and
They the pool until some tasks arrive for their execution.
Since The Task class doesn ' t return a result, it extends the Recursiveaction class. In the
recipe, your have used the recommended structure for the implementation of the task. If the
task has to update further than, it divides those set of elements into two blocks,
creates two Tas KS, and assigns a block to each task. You have used the "I" and "last
Attributes" in the "task class to know" range of positions this task has to upd Ate in the
List of products. You have used the "I" and "Last Attributes" to "use only one copy of the"
Products list and not create different lists F or each task.
To execute the subtasks this a task creates, it calls the InvokeAll () method. This is a
Synchronous call, and the task waits for the finalization of the subtasks before continuing
(potentially finishing) its execution. While the task is waiting to its subtasks, the worker thread
That is executing it takes another task that is waiting for execution and executes it. With
This is behavior, the Fork/join framework offers a more efficient task management than the
Runnable and callable objects themselves.
The InvokeAll () method of the Forkjointask class is one of the main differences
Between the Executor and the Fork/join framework. The Executor framework, all Tasks
Have to is sent to the executor, while in this case, the tasks include methods to execute and
Control the tasks inside the pool. You have used the InvokeAll () is in the Task class,
That's extends the Recursiveaction class that extends the Forkjointask class.
You are have sent a unique task to the pool to update all the list of products using the Execute ()
Method. In this case, it ' s a asynchronous call, and the main thread continues its execution.
You are have used some methods of the Forkjoinpool class to check the status and the
Evolution of the tasks that are running. The class includes more methods so can be useful
For this purpose. The monitoring a fork/join pool recipe for a complete list of
Those methods.
Finally, like and the Executor framework, you should finish Forkjoinpool using the
Shutdown () method.