• 一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历


    一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历

    liuyuhang原创,未经允许禁止转载

    本文举例使用的是JDK8的API

    目录:一点一点看JDK源码(〇)

    Spliterator为jdk1.8新增接口,由ArrayList.spliterator();获得其返回值对象Spliterator。

    该对象可以使用trySplit进行迭代器拆分,每次拆分后的迭代器接近上一次的二分之一。

    这是官方对于大数据量数组多线程遍历加工的一种趋势性指引。

    首先需要定义一个线程,

    然后需要将拆分后的迭代器传入该线程。

    执行start()方法让实现的run()方法进入就绪状态等待调用

    自定义线程代码如下:

     1 package com.FM.ArrayListStudy;
     2 
     3 import java.util.Spliterator;
     4 import java.util.function.Consumer;
     5 
     6 /**
     7  * 内部类,线程调用
     8  */
     9 public class MyThread4Spliterator<T> extends Thread {
    10     // 寄存变量
    11     private Spliterator<T> list;
    12 
    13     // 构造 - 传递参数
    14     public MyThread4Spliterator(Spliterator<T> list) {
    15         setList(list);
    16     }
    17 
    18     // 线程调用run
    19     @Override
    20     public void run() {
    21         Spliterator<T> list2 = getList();
    22         list2.forEachRemaining(new Consumer<T>() {
    23 
    24             @Override
    25             public void accept(T t) {
    26                 System.out.println(Thread.currentThread().getName()+" === "+t);
    27             }
    28 
    29         });
    30     }
    31 
    32     public Spliterator<T> getList() {
    33         return list;
    34     }
    35 
    36     public void setList(Spliterator<T> list) {
    37         this.list = list;
    38     }
    39 }

    定义并拆分迭代器代码如下,需要注意拆分规则

     1 package com.FM.ArrayListStudy;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Spliterator;
     5 
     6 public class SpliteratorInArrayListStudy {
     7     public static void main(String[] args) {
     8         // 初始化list
     9         ArrayList<Integer> list = new ArrayList<Integer>();
    10         for (int i = 0; i < 20; i++) {
    11             list.add(i + 1);
    12         }
    13         //四线程均分配比方式
    14         Spliterator<Integer> spliterator01 = list.spliterator();         //01中有20个元素
    15         Spliterator<Integer> spliterator02 = spliterator01.trySplit();    //01中有10个元素,02中有10个元素
    16         Spliterator<Integer> spliterator03 = spliterator01.trySplit();    //01中有5个元素,02中有10个元素,03中有5个元素
    17         Spliterator<Integer> spliterator04 = spliterator02.trySplit();    //01中有5个元素,02中有5个元素,03中有5个元素,04中有5个元素
    18         MyThread4Spliterator<Integer> t01 = new MyThread4Spliterator<Integer>(spliterator01);
    19         MyThread4Spliterator<Integer> t02 = new MyThread4Spliterator<Integer>(spliterator02);
    20         MyThread4Spliterator<Integer> t03 = new MyThread4Spliterator<Integer>(spliterator03);
    21         MyThread4Spliterator<Integer> t04 = new MyThread4Spliterator<Integer>(spliterator04);
    22         t01.setName("001");
    23         t02.setName("002");
    24         t03.setName("003");
    25         t04.setName("004");
    26         
    27         t01.start();
    28         t02.start();
    29         t03.start();
    30         t04.start();
    31     }
    32 }

    运行结果:

    以上!!

  • 相关阅读:
    27. 为什么线程执行要调用start而不是直接run
    25. ThreadLocal的使用场景
    23. 线程如何退出结束
    20. Java字符串格式化方法
    21. 时间的格式化方法
    19. 用过spring的线程池还是java的线程池?
    17. zookeeper的实现机制,有缓存,如何存储注册服务的
    面试-spring 那些事
    Apache服务器和tomcat服务器有什么区别?
    JNDI 和JDBC的区别
  • 原文地址:https://www.cnblogs.com/liuyuhangCastle/p/9704090.html
Copyright © 2020-2023  润新知