java中多线程读取同一个文件的不同位置,多线程读取文件

今天遇到一个问题,需要多个线程读取同一个文件的不同位置,提高效率,写代码验证了一下,把结果记录下来。

首先我们写个文件,然后多线程读取,以下是我实验的代码:

package com.alibaba.middleware.race;

import java.io.IOException;
import java.io.RandomAccessFile;

public class Test2 {

    public static void main(String[] args) throws IOException {
        byte[] th1 = "线程1".getBytes();
        byte[] th2 = "线程2".getBytes();
        byte[] th3 = "线程3".getBytes();
        final int len = th1.length;

        final RandomAccessFile raf = new RandomAccessFile(
                "F:/tianchi/index.data", "rw");
        raf.seek(1);
        raf.write(th1);
        raf.seek(200);
        raf.write(th2);
        raf.seek(300);
        raf.write(th3);

        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                while (true) {
                    byte[] b = new byte[len];
                    try {
                        raf.seek(1);
                        raf.read(b);

                        if ("线程1".equals(new String(b))) {
                            System.out.println("ok");
                        } else {

                            System.out.println("线程1-" + new String(b));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        };
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        byte[] b = new byte[len];
                        raf.seek(200);
                        raf.read(b);
                        if ("线程2".equals(new String(b))) {
                            System.out.println("ok");
                        } else {

                            System.out.println("线程2-" + new String(b));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Runnable runnable3 = new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        byte[] b = new byte[len];
                        raf.seek(300);
                        raf.read(b);
                        if ("线程3".equals(new String(b))) {
                            System.out.println("ok");
                        } else {

                            System.out.println("线程3-" + new String(b));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        for (int i = 0; i < 20; i++) {
            new Thread(runnable1).start();
            new Thread(runnable2).start();
            new Thread(runnable3).start();
        }
        System.out.println("主线程完了");

    }

}

测试结果如下,会出现这样的问题:

ok
线程3-
线程1-线程3
ok
ok

说明,多个线程读取同一个文件,不加锁,是会出错的。
然后我们做如下改进。

代码:

package com.alibaba.middleware.race;

import java.io.IOException;
import java.io.RandomAccessFile;

public class Test2 {

    public static void main(String[] args) throws IOException {
        byte[] th1 = "线程1".getBytes();
        byte[] th2 = "线程2".getBytes();
        byte[] th3 = "线程3".getBytes();
        final int len = th1.length;

        final RandomAccessFile raf = new RandomAccessFile(
                "F:/tianchi/index.data", "rw");
        raf.seek(1);
        raf.write(th1);
        raf.seek(200);
        raf.write(th2);
        raf.seek(300);
        raf.write(th3);

        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                while (true) {
                    byte[] b = new byte[len];
                    try {
                        synchronized (raf) {
                            raf.seek(1);
                            raf.read(b);
                        }

                        if ("线程1".equals(new String(b))) {
                            System.out.println("ok");
                        } else {

                            System.out.println("线程1-" + new String(b));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        };
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        byte[] b = new byte[len];
                        synchronized (raf) {
                            raf.seek(200);
                            raf.read(b);
                        }
                        if ("线程2".equals(new String(b))) {
                            System.out.println("ok");
                        } else {

                            System.out.println("线程2-" + new String(b));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Runnable runnable3 = new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        byte[] b = new byte[len];
                        synchronized (raf) {
                            raf.seek(300);
                            raf.read(b);
                        }
                        if ("线程3".equals(new String(b))) {
                            System.out.println("ok");
                        } else {

                            System.out.println("线程3-" + new String(b));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        for (int i = 0; i < 20; i++) {
            new Thread(runnable1).start();
            new Thread(runnable2).start();
            new Thread(runnable3).start();
        }
        System.out.println("主线程完了");

    }

}

对文件的访问加一个锁,这样就可以了,测试结果是对的,我就不贴了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值