处理10G数据用多线程搞定了!

本文介绍如何使用Java处理10GB的大文件,通过多线程读取并统计文件中18-70岁人群数量,找出重复次数最多的数字。文章详细分析了问题解决步骤,包括创建文件、多线程读取、数据处理接口及其实现,最终在293秒内完成统计,结果正确。
摘要由CSDN通过智能技术生成


话接前回, https://editor.csdn.net/md/?articleId=125025105网上大部分文章都照抄照搬,但是这个文章里的代码还是有问题的。

  有一个10G文件的数据,里面包含了18-70之间的整数,分别表示18-70岁的人群数量统计,假设年龄范围分布均匀,分别表示系统中所有用户的年龄数,找出重复次数最多的那个数。

  最终我也重新写了个代码,处理起来应该是对的了,代码并没有在他的基础上进行改变,而是重新写了,至于创建10G文件的话,用的还是原来的,接下来就记录一下怎么处理的?

  我写的示例结构如下:

1.创建文件,大小为10G左右

  创建文件的格式为:数据全都在17-70之间,包括17和70,每一百万个数据为一行,数据之间用","分隔开,最后行末有一个换行符,100万条数据大概4M,10G的文件总共有2500行左右。
创建代码如下:

/**
 * 创建10G的文件
 */
public class GenerateData {
   
    private static Random random = new Random();

    public static int generateRandomData(int start, int end) {
   
        return random.nextInt(end - start + 1) + start;
    }

    /**
     * 产生10G的 1-1000的数据在F盘
     */
    public void generateData() throws IOException {
   
        File file = new File("F:\\ User.dat");
        if (!file.exists()) {
   
            try {
   
                file.createNewFile();
            } catch (IOException e) {
   
                e.printStackTrace();
            }
        }
        int start = 18;
        int end = 70;
        long startTime = System.currentTimeMillis();
        BufferedWriter bos = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
        for (long i = 1; i < Integer.MAX_VALUE * 1.7; i++) {
   
            String data = generateRandomData(start, end) + ",";
            bos.write(data);
            // 每100万条记录成一行,100万条数据大概4M
            if (i % 1000000 == 0) {
   
                bos.write("\n");
            }
        }
        System.out.println("写入完成! 共花费时间:" + (System.currentTimeMillis() - startTime) / 1000 + " s");
        bos.close();
    }

    public static void main(String[] args) {
   
        GenerateData generateData = new GenerateData();
        try {
   
            generateData.generateData();
        } catch (IOException e) {
   
            e.printStackTrace();
        }
    }
}

  这个代码是独立的,只是用于创建10G的文件,与下边的代码无关。

差不多花了4min

2.问题分析

在一个10G文件的数据,里面包含了18-70之间的整数,找出重复次数最多的那个数。
  第一步:应该找出每一行中的出现的数,以及这个数出现的次数,之后进行形成一个映射,也就是一个Map,这样可以节约内存空间。
  比如:20这个数在第一行中出现了5次,那么就形成一个HashMap结构。key=20,value=5,

 Map<Integer, Integer> mapSum = new HashMap<Integer, Integer>();

  第二步:用多线程进行读取,开启多个线程对文件进行每行读取,当读到完整一行时就将其中的数据以及出现的次数用Map结构存储并返回。

注意:每个线程都需要返回一个Map,所以需要实现Callable接口。

  第三步:将每个线程返回的Map进行接受,并对Map进行汇总,统计出所有Map中的数据集。

代码如下:

(1)主线程(MultiThreadReadByLine 类)
public class MultiThreadReadByLine {
   
    public static void main(String[] args) {
   
        FileReader fileReader = new FileReader("F:\\ data.dat", 1024000, 20);
        fileReader.registerHanlder(new FileLineDataHandler());
        //统计所有map
        Map<Integer, Integer> mapSum = new HashMap<
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值