java产生一亿个随机数多线程写入同一个文件

主要我知道的三种方法

  1. 直接使用缓冲流写入文件,这个不做过多说明
public class Testmain {
    public static void main(String[] args) {
        Random random = new Random();
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\work\\ten\\jm.txt"));
            long start = System.currentTimeMillis();
            for (int i = 0; i < 1024 * 1024 * 128; i++) {
                bw.write((-999) + random.nextInt(10999) + "\n");
            }
            bw.close();
            System.out.print(System.currentTimeMillis() - start + "ms");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2 使用多线程一个读一个写,因为产生随机数也是非常耗时的

/*
* 将数据放在缓冲区中
* */

public class Read implements Runnable {
    StringBuffer buffer;

    @Override
    public void run() {
        int a = 1024 * 1024 * 128;
        Random random = new Random();
        buffer = new StringBuffer(a);
        for (int i = 0; i <1024*1024*32 ; i++) {
            buffer.append((-999) + random.nextInt(10999) + "\n");
        }
    }

    public String jm() {
        run();
        return buffer.toString();
    }
}
/*
 * 将数据写入文件
 * */

public class Write implements Runnable {
    @Override
    public void run() {
        Read read = new Read();
        String jm = read.jm();
        long start = System.currentTimeMillis();
        synchronized (this) {
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\work\\ten\\jm.txt"));
                for (int i = 0; i < 4; i++) {
                    bw.write(jm);
                }
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start + "ms");
    }
}

主线程

/*
* 主线程类
* */

public class Theradmain {
    public static void main(String[] args) {
        Read read = new Read();
        Write write = new Write();
        Thread t1 = new Thread(read);
        Thread t2 = new Thread(write);

        t1.start();
        t2.start();
    }
}

可以根据自己电脑的内存那些来看开几个线程效率最高,这个可以自己跑跑看,需要自己做测试,最好在固态硬盘上测试,因为数据量比较大,固态硬盘一般是C盘

3 用到了RandomAccessFile这个类,此类非IO流类,详细的用法可以自己看看API

这个方法主要的思想:
我们想要把数据同步一起写入到文件中,这个方法给我们提供了写入文件时的位置与大小(通俗来说,就是我们写一亿行数据,我们把它分成几部分,然后同步写入文件中,每一个写入的位置不一样,不用像多线程一样顺序的写入)

具体的代码

*
 * 将数据同时写入同一个文件的不同位置
 *
 * */


public class Three implements Runnable {
    private int offset;   //起始量
    private int len;      //写入文件的数量

    @Override
    public void run() {
        long start = System.currentTimeMillis();
        try {
            Random random = new Random();
            RandomAccessFile rw = new RandomAccessFile("D:\\work\\ten\\jm.txt", "rw");
            FileChannel channel = rw.getChannel();   //获取通道
            rw.seek(offset); //写入文件的起始位置
            rw.setLength(len); //设置文件的长度
            //FileLock fileLock = channel.tryLock(offset,len,true); //文件锁,在windows上不能同时读写一个文件
            for (int i = 0; i < 1024 * 1024 * 128; i++) {
                rw.writeBytes((-999) + random.nextInt(10999) + "\n");
            }
            //fileLock.release();  //释放文件锁
            rw.close();
            channel.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start + "ms");
    }

    public Three(int offset, int len) {
        this.offset = offset;
        this.len = len;
    }
}

主线程

public class ThreeMain {
    public static void main(String[] args) {
        int length = 1024 * 1024 * 128;
        Three[] test = new Three[4];//创建Thrr类型的数组,将数据存入数组中
        //起始位置和每一部分很好计算
        //起始位置你看你分成几部分,然后把length当成单位一就行了,每一部分的量就用总量/分成几部分
        test[0] = new Three(length * 0, length / 4);
        test[1] = new Three(length / 4, length / 4);
        test[2] = new Three(length / 2, length / 4);
        test[3] = new Three(length / 12, length / 4);

        Thread t1 = new Thread(test[0]);
        Thread t2 = new Thread(test[1]);
        Thread t3 = new Thread(test[2]);
        Thread t4 = new Thread(test[3]);

        t1.start();
        t2.start();
        t3.start();
        t4.start();

这个方法看起来很不错,但是我测了一下,写入的速度有点慢,当然自己还可以在优化

注意: 这个方法在windows操作系统上是不行的,因为用到了文件锁FileLock fileLock,你不加锁,写入文件会出现错误

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值