java-jdk7-forkjoin带有返回值

来自并发编程网: http://ifeve.com/fork-join-3/

如果这个任务必须解决一个超过预定义大小的问题,你应该将这个任务分解成更多的子任务,并且用Fork/Join框架来执行这些子任务。当这些子任务完成执行,发起的任务将获得所有子任务产生的结果 ,对这些结果进行分组,并返回最终的结果。最终,当在池中执行的发起的任务完成它的执行,你将获取整个问题地最终结果。

1, 生成二维数组模拟文档: 

package com.wenbronk.forkjoin.withresult;

import java.util.Random;

/**
 * Created by wenbronk on 2017/7/26.
 */
public class Document {

    private String words[] = {"the", "hello", "goodbye", "pack", "java", "thread", "pool", "random", "class", "main"};

    public String[][] generateDocument(int numLines, int numWords, String word) {
        int counter = 0;
        String[][] document = new String[numLines][numWords];
        Random random = new Random();

        // 填充数组
        for (int i=0; i<numLines; i++){
            for (int j=0; j<numWords; j++) {
                int index=random.nextInt(words.length);
                document[i][j]=words[index];
                if (document[i][j].equals(word)){
                    counter++;
                }
            }
        }
        System.out.println(document.length + ": " + document[document.length - 1].length);

        System.out.println("DocumentMock: The word appears " + counter + " times in the document");
        return document;
    }

}

2, 对模拟文档的进行行拆分

package com.wenbronk.forkjoin.withresult;

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

/**
 * Created by wenbronk on 2017/7/26.
 */
public class DocumentTask extends RecursiveTask<Integer> {

    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 = (start + end) / 2;
            DocumentTask task1 = new DocumentTask(document, start, mid, word);
            DocumentTask task2 = new DocumentTask(document, mid, end, word);

            invokeAll(task1, task2);
            try {
                result = groupResults(task1.get(), task2.get());
            }catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private int groupResults(Integer integer, Integer integer1) {
        return integer + integer1;
    }

    /**
     * 要查找的单词
     */
    private int processLines(String[][] document, int start, int end, String word) {
        ArrayList<LineTask> 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 (LineTask task : tasks) {
        for (int i = 0; i < tasks.size(); i++) {
            LineTask task = tasks.get(i);
            try {
//                Thread.sleep(100);
                result += task.get();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}

3, 对行进行单词拆分

package com.wenbronk.forkjoin.withresult;

import java.util.concurrent.RecursiveTask;

/**
 * 统计单词在一行出现的次数
 * Created by wenbronk on 2017/7/27.
 */
public class LineTask extends RecursiveTask<Integer> {
    private static final long seriaVersionUID = 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 = (start + end) / 2;
            LineTask task1 = new LineTask(line, start, mid, word);
            LineTask task2 = new LineTask(line, mid, end, word);
            invokeAll(task1, task2);
            try {
                result = groupResult(task1.get(), task2.get());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 合并2个数值的值, 返回结果
     * @return
     */
    private Integer groupResult(Integer num1, Integer num2) {
        return num1 + num2;
    }

    /**
     * 查找行中出现word的次数
     */
    private Integer count(String[] line, int start, int end, String word) {
        int counter = 0;
        for (int i = start; i < end; i++) {
            if (word.equals(line[i])) {
                counter ++;
            }
        }
//        try {
//            Thread.sleep(10);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        return counter;
    }
}

4, 入口执行类

package com.wenbronk.forkjoin.withresult;

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

/**
 * Created by wenbronk on 2017/7/27.
 */
public class CountMain {

    public static void main(String[] args) {
        Document document = new Document();
        String[][] documents = document.generateDocument(100, 1000, "random");

        DocumentTask task = new DocumentTask(documents, 0, 100, "random");
        ForkJoinPool pool = new ForkJoinPool();
        pool.execute(task);

        do {
            System.out.printf("******************************************\n");
            System.out.printf("Main: Parallelism: %d\n",pool.getParallelism());
            System.out.printf("Main: Active Threads: %d\n",pool.getActiveThreadCount());
            System.out.printf("Main: Task Count: %d\n",pool.getQueuedTaskCount());
            System.out.printf("Main: Steal Count: %d\n",pool.getStealCount());
            System.out.printf("******************************************\n");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (!task.isDone());

        pool.shutdown();

        try {
            System.out.printf("Main: The word appears %d in the document ", task.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

posted @ 2017-07-27 17:47  bronk  阅读(776)  评论(0编辑  收藏  举报