Java并发编程-25-合并任务的结果

一、合并任务的结果

Fork/Join 框架提供了执行任务并返回结果的能力,这些类型的任务都是通过RecursiveTask类实现的

RecursiveTask 类继承了ForkJoinTask类,并且实现了由执行器框架提供的Future接口

二、get()方法

get()方法是Future接口提供的,RecursiveTask类实现了这个接口,可以直接调用这个方法,返回Task任务的返回的结果

三、模拟

一个文档任务:它将遍历文档中的每一行来查找这个词

一个行任务:他将在给定的行中查找这个词

将文档任务分解为行任务

package com.currency.forkandjoin;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;

/**
 * 这个任务用来计算所要查找的单词在行中出现的次数
 * 
 * @author Nicholas
 *
 */
public class DocumentTask extends RecursiveTask {

	private static final long serialVersionUID = 1L;

	private String[][] document;
	private int start, end;
	private String word;

	public DocumentTask(String[][] document, int start, int end, String word) {
		this.document = document;
		this.start = start;
		this.end = end;
		this.word = word;
	}

	@Override
	protected Integer compute() {
		int result = 0;
		if (end - start < 10)
			result = processLines(document, start, end, word);
		else {
			int mid = (end + start) / 2;
			DocumentTask documentTask1 = new DocumentTask(document, start, mid,
					word);
			DocumentTask documentTask2 = new DocumentTask(document, mid, end,
					word);
			invokeAll(documentTask1, documentTask2);
			try {
				result = groupResults(documentTask1.get(), documentTask2.get());
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		}
		return new Integer(result);
	}

	public Integer processLines(String[][] document, int start, int end,
			String word) {
		List tasks = new ArrayList();

		for (int i = start; i < end; i++) {
			LineTask lineTask = new LineTask(document[i], 0,
					document[i].length, word);
			tasks.add(lineTask);
		}
		invokeAll(tasks);
		int result = 0;
		for (int i = 0; i < tasks.size(); i++) {
			LineTask lineTask = tasks.get(i);

			try {
				result = result + lineTask.get();
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		}

		return new Integer(result);
	}

	public Integer groupResults(Integer number1, Integer number2) {
		return (number1 + number2);
	}
}

package com.currency.forkandjoin;

import java.util.Random;

/**
 * 生成一个字符串矩阵来模拟文档
 * 
 * @author Nicholas
 *
 */
public class DocumentMock {
	private String[] words = { "the", "hello", "world", "goodbye", "class",
			"main", "java", "c++", "python" };

	public String[][] generateDocument(int mumberLines, int numberWords,
			String word) {
		int counter = 0;
		String[][] documens = new String[mumberLines][numberWords];
		Random random = new Random();
		for (int i = 0; i < mumberLines; i++) {
			for (int j = 0; j < numberWords; j++) {
				int index = random.nextInt(words.length);
				documens[i][j] = words[index];
				if (documens[i][j].equals(word))
					counter++;
			}
		}

		// 打印目标词在整个文档中出现的次数
		System.out.println("DocumentMock : The word appears " + counter
				+ " times in the documents");

		return documens;
	}
}

package com.currency.forkandjoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;

/**
 * 计算目标词在一行中出现的次数
 * @author Nicholas
 *
 */
public class LineTask extends RecursiveTask {
	
	private static final long serialVersionUID = 1L;

	private String[] line;
	private int start, end;
	private String word;

	public LineTask(String[] line, int start, int end, String word) {
		this.line = line;
		this.start = start;
		this.end = end;
		this.word = word;
	}

	@Override
	protected Integer compute() {
		Integer result = null;
		if (end - start < 100)
			result = Count(line, start, end, word);
		else {
			int mid = (end + start) / 2;
			LineTask lineTask1 = new LineTask(line, start, mid, word);
			LineTask lineTask2 = new LineTask(line, mid, end, word);
			invokeAll(lineTask1, lineTask2);

			try {
				result = groupResults(lineTask1.get(), lineTask2.get());
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	public Integer Count(String[] line, int start, int end, String word) {
		int counter = 0;
		for (int i = start; i < end; i++) {
			if (line[i].equals(word))
				counter++;
		}

		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return counter;
	}

	public Integer groupResults(Integer number1, Integer number2) {
		return (number1 + number2);
	}
}

package com.currency.forkandjoin;

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

public class Main {

	public static void main(String[] args) {
		DocumentMock documentMock = new DocumentMock();
		String[][] document = documentMock.generateDocument(100, 1000, "the");

		DocumentTask documentTask = new DocumentTask(document, 0, 100, "the");

		ForkJoinPool forkJoinPool = new ForkJoinPool();
		forkJoinPool.execute(documentTask);

		do {
			System.out
					.println("****************************************************");
			System.out.println("Main : Parallelism : "
					+ forkJoinPool.getParallelism());
			System.out.println("Main : Active Threads : "
					+ forkJoinPool.getActiveThreadCount());
			System.out.println("Main : Task Count : "
					+ forkJoinPool.getQueuedTaskCount());
			System.out.println("Main : Steal Count : "
					+ forkJoinPool.getStealCount());
			System.out
					.println("****************************************************");
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (!documentTask.isDone());

		forkJoinPool.shutdown();

		try {
			forkJoinPool.awaitTermination(1, TimeUnit.DAYS);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		try {
			System.out.println("Main : The word appears " + documentTask.get()
					+ " in the documents");

		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
	}
}

结果:

DocumentMock : The word appears 10997 times in the documents
****************************************************
Main : Parallelism : 4
Main : Active Threads : 1
Main : Task Count : 0
Main : Steal Count : 0
****************************************************
****************************************************
Main : Parallelism : 4
Main : Active Threads : 4
Main : Task Count : 32
Main : Steal Count : 0
****************************************************
****************************************************
Main : Parallelism : 4
Main : Active Threads : 4
Main : Task Count : 16
Main : Steal Count : 0
****************************************************
****************************************************
Main : Parallelism : 4
Main : Active Threads : 4
Main : Task Count : 19
Main : Steal Count : 2
****************************************************
****************************************************
Main : Parallelism : 4
Main : Active Threads : 2
Main : Task Count : 11
Main : Steal Count : 6
****************************************************
Main : The word appears 10997 in the documents



你可能感兴趣的:(Java,并发编程,Java并发编程)