Fork/Joinスレッドプールの作成


製品の価格を更新するタスクを実現します.最初のタスクは、リスト内のすべての要素を更新する責任を負います.参照サイズとして10を使用します.1つのタスクが10以上の要素を更新する必要がある場合は、このリストを2つの部分に分解し、それぞれの部分の製品価格を更新するために2つのタスクを作成します.
package com.xingfu.wx_1;
/**
 *           
 * @author W,x
 * @version     :2015 4 14    4:10:26
 * 
 */
public class Product {
	
	private String name;
	private double price;
	public Product(String name, double price) {
		super();
		this.name = name;
		this.price = 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;
	}
	
}

ランダムな製品リストを生成するProductListGeneratorのクラスを作成します.
package com.xingfu.wx_1;

import java.util.ArrayList;
import java.util.List;

/**
 *           
 * @author W,x
 * @version     :2015 4 14    4:11:50
 * 
 */
public class ProductListGenerator {
	public List generate(int size){
		Listret=new ArrayList();
		Product product;
		for(int i=0;i

Taskのクラスを作成し、RecursiveActionクラスを継承
package com.xingfu.wx_1;

import java.util.List;
import java.util.concurrent.RecursiveAction;

import com.xingfu.wx.Utils;

/**
 *
 * @author W,x
 * @version     :2015 4 14    4:14:06
 * 
 */
public class Task extends RecursiveAction{

	/**
	 * 
	 */
	private static final long serialVersionUID = 5622480283632727215L;

	private List products;
	
	private int first;
	
	private int last;
	
	/**
	 *     increment   double  ,            
	 */
	private double increment;
	
	
	public Task(List products, int first, int last, double increment) {
		super();
		this.products = products;
		this.first = first;
		this.last = last;
		this.increment = increment;
	}


	@Override
	protected void compute() {
		if(last-first<10){
			updatePrices();
		}else{
			int middle=(last+first)/2;
			Utils.print("Task : Pending tasks:%s
",getQueuedTaskCount()); Task t1=new Task(products,first,middle+1,increment); Task t2=new Task(products, middle+1,last,increment); invokeAll(t1,t2); } } private void updatePrices() { for(int i=first;i
package com.xingfu.wx_1;

import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

import com.xingfu.wx.Utils;

/**
 * 
 * @author W,x
 * @version     :2015 4 14    4:19:34
 * 
 */
public class Main {
	public static void main(String[] args) {
		ProductListGenerator generator = new ProductListGenerator();
		//  10000      
		List products = generator.generate(10000);
		//      Task              ,  first0,  last        。10000
		Task task = new Task(products, 0, products.size(), 0.20);
		ForkJoinPool pool = new ForkJoinPool();
		pool.execute(task);
		do {
			Utils.print("Main : Thread Count: %d
", pool.getActiveThreadCount()); Utils.print("Main: Thread Steal:%d
", pool.getStealCount()); Utils.print("Main: Parallelism:%d
", pool.getParallelism()); try { TimeUnit.MILLISECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } } while (!task.isDone()); // pool.shutdown(); // if (task.isCompletedNormally()) { Utils.print("Main:The process has completed normally.
"); } for (int i = 0; i < products.size(); i++) { Product product = products.get(i); if (product.getPrice() != 12) { Utils.print("Product %s :%f
", product.getName(), product.getPrice()); } } System.out.println("Main: End of the program.
"); } }

さぎょうげんり
ForkJoinPoolオブジェクトと、スレッドプールで実行されるForkJoinTaskのサブクラスを作成しました.パラメータなしでForkJoinPoolオブジェクトを構築するため、デフォルトの構成を実行します.スレッド数がコンピュータCPU数に等しいスレッドプールを作成し、ForkJoinPoolオブジェクトを作成すると、スレッドも作成され、オンライン・プログラム・プールでタスクの到着を待ってから実行が開始されます.
TaskクラスはRecursiveActionクラスを継承しているため、結果は返されません.ここでは,タスクを実現するために推奨される構造を用いた.タスクが10個以上の製品を更新する必要がある場合は、これらの要素を2つの部分に分割し、2つのタスクを作成し、分割された部分を新しく作成されたタスクに割り当てます.TaskクラスのFirstプロパティとlastプロパティを使用すると、タスクが更新される製品リストの位置範囲がわかります.firstプロパティとlastプロパティを使用して、各タスクに対して異なる製品リストを作成することなく、製品リストのコピーを1つだけ操作しました.
invokeAll()メソッドを呼び出して、1つのプライマリ・タスクによって作成された複数のサブタスクを実行します.これは、サブタスクの完了を待って実行を続行する(または終了する)同期呼び出しです.1つのプライマリ・タスクがサブタスクを待機している場合、このタスクを実行する作業者スレッドは、別の待機タスクを受け入れて実行を開始します.この行為があったからこそ、
したがって、Fork/joinフレームワークは、RunnableおよびCallableオブジェクトよりも効率的なタスク管理メカニズムを提供する.
ForkJoinTaskクラスのinvokeAll()メソッドは、エフェクタフレームワークとFork/joinフレームワークの主な違いの1つです.エフェクタフレームワークでは、すべてのタスクをエフェクタに送信する必要があります.スレッドプールには実行対象メソッドのタスクが含まれています.タスクの制御もオンラインスレッドプールで行われます.TaskクラスではinvokeAll()メソッドを使用し、TaskはRecursiveActionクラスを継承し、RecursiveActionはForkJoinTaskクラスを継承します.