美文网首页
Java并发之JDK并发包(3)

Java并发之JDK并发包(3)

作者: 辣公公 | 来源:发表于2016-11-25 23:34 被阅读36次

    实战Java高并发程序设计笔记


    分而治之:Fork/Join框架

    1. ForkJoinPool线程池,对于fork而言并不急于开启线程,而是提交给ForkJoinPool线程池处理,以节省资源。使用ForkJoinPool进行数据处理的总机构图如下


      Fork/join执行逻辑
    2. ForkJoinPool 简单例子:计算1到10000的和
        private static final int THRESHOLD = 1000;
        public static void main(String args[]) throws ExecutionException, InterruptedException {
            System.out.println(System.currentTimeMillis() / 1000);
            System.out.println(sum(1, 10000));
            System.out.println(System.currentTimeMillis() / 1000);
            System.out.println("¥¥¥¥¥¥¥¥¥");
            System.out.println(System.currentTimeMillis() / 1000);
            ForkJoinPool pool = new ForkJoinPool();
            ForkJoinTask<Long> task = pool.submit(new CountTask(1, 10000));
            System.out.println( task.get());
            System.out.println(System.currentTimeMillis() / 1000);
        }
    
    public static long sum(long start, long end) {
            if (end - start + 1 > THRESHOLD) {
                return sum(start, (start + end) / 2) + sum((start + end) / 2, end);
            } else {
                long sum = 0;
                for (long i = start; i <= end; i++) {
                    sum += i;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return sum;
            }
        }
    
    static class CountTask extends RecursiveTask<Long> {
            private long end;
            private long start;
    
            public CountTask(long start, long end) {
                this.end = end;
                this.start = start;
            }
    
            @Override
            protected Long compute() {
                if (end - start + 1 > THRESHOLD) {
                    CountTask task1 = new CountTask(start, (start + end) / 2);
                    CountTask task2 = new CountTask((start + end) / 2, end);
                    task1.fork();
                    task2.fork();
                    return task1.join() + task2.join();
                } else {
                    long sum = 0;
                    for (long i = start; i <= end; i++) {
                        sum += i;
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return sum;
                }
            }
        }
    
    • 运行结构:
      1480090749
      50080000
      1480090765
      ¥¥¥¥¥¥¥¥¥
      1480090765
      50080000
      1480090768
      可以看出,sum 计算需要16秒,而使用ForkJoinPool 仅仅需要3秒
    • 使用ForkJoin时,任务的划分层次不能太深否则可能出现两种情况
      • 系统内线程数量越来越多。导致性能严重下降
      • 函数的调用层次变得很深,最终导致堆栈溢出

    相关文章

      网友评论

          本文标题:Java并发之JDK并发包(3)

          本文链接:https://www.haomeiwen.com/subject/wufppttx.html