ForkJoinPool类并行处理

来源:互联网 发布:永琪因知画误会小燕子 编辑:程序博客网 时间:2024/05/17 18:02

我们常常听说CPU拥有多核,但它对执行程序有什么大大的帮助呢?相对于CPU单核,多核CPU可以把一个任务比较大的程序分成几个任务比较小的程序,让这些小程序放到处理器上的多个核心同时处理,最后再把这些执行结果合并起来,这样可以大大提升运行效率,就拿个生活中的例子来描述CPU多核的用处吧:你去大学食堂打饭时,食堂如果仅仅有一个打饭窗口,我们学生是不是要排很长的队伍去等待,直到前面的人打完饭,才轮到你了,但如果食堂加了几个打饭窗口,那么我们这些可以分散到几个窗口去打饭,就不用排那么长的队伍了,这样你打到饭的时间是不是少了很多啊,这里打饭窗口就类似于多核CPU的用处。
Java就提供了一个ForkJoinPool类来支持并行处理程序。
代码例子:

**没有返回值得并行计算**//继承RecursiveAction来实现"可分解"的任务class PrintTask extends RecursiveAction{    // 每个“小任务”只最多只打印50个数    private static final int THRESHOLD = 10;    private int start;    private int end;    // 打印从start到end的任务    public PrintTask(int start, int end)    {        this.start = start;        this.end = end;    }    @Override    protected void compute()     {        // 当end与start之间的差小于THRESHOLD时,开始打印        if(end - start < THRESHOLD)        {            for (int i = start ; i < end ; i++ )            {                System.out.println(Thread.currentThread().getName()                    + "的i值:" + i);            }        }        else        {            // 如果当end与start之间的差大于THRESHOLD时,即要打印的数超过50个            // 将大任务分解成两个小任务。            int middle = (start + end) /2;            PrintTask left = new PrintTask(start, middle);            PrintTask right = new PrintTask(middle, end);            // 并行执行两个“小任务”            left.fork();            right.fork();        }    }}public class ForkJoinPoolTest{    public static void main(String[] args)         throws Exception    {        ForkJoinPool pool = new ForkJoinPool();        // 提交可分解的PrintTask任务        pool.submit(new PrintTask(0 , 50));        //线程阻塞,等待所有任务完成        pool.awaitTermination(2, TimeUnit.SECONDS);        // 关闭线程池        pool.shutdown();    }}

运行结果:
ForkJoinPool-1-worker-3的i值:18
ForkJoinPool-1-worker-4的i值:37
ForkJoinPool-1-worker-1的i值:43
ForkJoinPool-1-worker-1的i值:44
ForkJoinPool-1-worker-1的i值:45
ForkJoinPool-1-worker-1的i值:46
ForkJoinPool-1-worker-1的i值:47
ForkJoinPool-1-worker-1的i值:48
ForkJoinPool-1-worker-1的i值:49
ForkJoinPool-1-worker-1的i值:25
ForkJoinPool-1-worker-1的i值:26
ForkJoinPool-1-worker-1的i值:27
ForkJoinPool-1-worker-1的i值:28
ForkJoinPool-1-worker-1的i值:29
ForkJoinPool-1-worker-1的i值:30
ForkJoinPool-1-worker-1的i值:6
ForkJoinPool-1-worker-1的i值:7
ForkJoinPool-1-worker-1的i值:8
ForkJoinPool-1-worker-1的i值:9
ForkJoinPool-1-worker-2的i值:31
ForkJoinPool-1-worker-1的i值:10
ForkJoinPool-1-worker-4的i值:38
ForkJoinPool-1-worker-3的i值:19
ForkJoinPool-1-worker-4的i值:39
ForkJoinPool-1-worker-4的i值:40
ForkJoinPool-1-worker-1的i值:11
ForkJoinPool-1-worker-2的i值:32
ForkJoinPool-1-worker-1的i值:0
ForkJoinPool-1-worker-4的i值:41
ForkJoinPool-1-worker-3的i值:20
ForkJoinPool-1-worker-4的i值:42
ForkJoinPool-1-worker-1的i值:1
ForkJoinPool-1-worker-2的i值:33
ForkJoinPool-1-worker-1的i值:2
ForkJoinPool-1-worker-4的i值:12
ForkJoinPool-1-worker-3的i值:21
ForkJoinPool-1-worker-4的i值:13
ForkJoinPool-1-worker-1的i值:3
ForkJoinPool-1-worker-2的i值:34
ForkJoinPool-1-worker-1的i值:4
ForkJoinPool-1-worker-4的i值:14
ForkJoinPool-1-worker-3的i值:22
ForkJoinPool-1-worker-4的i值:15
ForkJoinPool-1-worker-1的i值:5
ForkJoinPool-1-worker-2的i值:35
ForkJoinPool-1-worker-2的i值:36
ForkJoinPool-1-worker-4的i值:16
ForkJoinPool-1-worker-3的i值:23
ForkJoinPool-1-worker-4的i值:17
ForkJoinPool-1-worker-3的i值:24
有返回值的并行计算

//继承RecursiveTask来实现"可分解"的任务class CalTask extends RecursiveTask<Integer>{    // 每个“小任务”只最多只累加20个数    private static final int THRESHOLD = 20;    private int arr[];    private int start;    private int end;    // 累加从start到end的数组元素    public CalTask(int[] arr , int start, int end)    {        this.arr = arr;        this.start = start;        this.end = end;    }    @Override    protected Integer compute()    {        int sum = 0;        // 当end与start之间的差小于THRESHOLD时,开始进行实际累加        if(end - start < THRESHOLD)        {            for (int i = start ; i < end ; i++ )            {                sum += arr[i];            }            return sum;        }        else        {            // 如果当end与start之间的差大于THRESHOLD时,即要打印的数超过20个            // 将大任务分解成两个小任务。            int middle = (start + end) /2;            CalTask left = new CalTask(arr , start, middle);            CalTask right = new CalTask(arr , middle, end);            // 并行执行两个“小任务”            left.fork();            right.fork();            // 把两个“小任务”累加的结果合并起来            return left.join() + right.join();        }    }}public class Sum{    public static void main(String[] args)        throws Exception    {        int[] arr = new int[100];        Random rand = new Random();        int total = 0;        // 初始化100个数字元素        for (int i = 0 , len = arr.length; i < len ; i++ )        {            int tmp = rand.nextInt(20);            // 对数组元素赋值,并将数组元素的值添加到total总和中。            total += (arr[i] = tmp);        }        System.out.println(total);        ForkJoinPool pool = new ForkJoinPool();        // 提交可分解的CalTask任务        Future<Integer> future = pool.submit(new CalTask(arr , 0 , arr.length));        System.out.println(future.get());        // 关闭线程池        pool.shutdown();    }}

运行结果:
969
969

0 0
原创粉丝点击