当多个线程写入文件时,使用BufferReader读取文件

时间:2014-07-01 09:17:19

标签: java multithreading file thread-safety

全部,我正在尝试读取将由多个线程写入的文件,我将使用BufferedReader在线程中读取该文件。

代码如下所示。

FileReader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader);
String detail;
while ((detail =br.readLine()) != null)
{
   ...
}

目前似乎工作正常。但我对此有一些疑问。 如果这个问题听起来很傻。请不要嘲笑我。感谢。

循环是否可能永远不会被破坏?因为其他线程正在写入文件。所以readLine()可能永远不会返回null?

更新

假设有3个线程(T1,T2,T3)。

T1和T2是作家。

T3是读者。

代码按以下顺序运行。

1.当前文件行号为100。

2.T1将一行写入文件。(文件行增加到101)

3.T3读取文件的最后一行(101)。下一次读取将为空。

4.T2在文件中附加一行。(文件行增加到102)

5.T3再次读取....(它是否返回null?因为T2在T3读取之前刚刚将新行添加到文件中。)

请提前帮助查看。谢谢。

3 个答案:

答案 0 :(得分:3)

是的,循环可能永远不会结束(至少在内存不足之前)。这里有一些代码来证明它:

public class test {

    public static void main(String[] args) {
// start thread to write to file
        new Thread(new Runnable() {
            @Override
            public void run() {
                FileWriter writer;
                try {
                    int i = 1;
                    writer = new FileWriter("D:\\text.txt");
                    writer.append("line"+ i++ + "\n");
                    writer.flush();
                    while (true)
                    {
                        writer.append("line"+ i++ + "\n");
                        writer.flush();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }).start();

        try {
            Thread.sleep(500);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        // start thread to read file
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    FileReader reader = new FileReader("D:\\text.txt");
                    BufferedReader br = new BufferedReader(reader);
                    String detail;
                    while ((detail =br.readLine()) != null)
                    {
                        System.out.println(detail);
                    }
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }).start();

    }
}

答案 1 :(得分:0)

我做了一些实验。

一次日食作为作家运行程序。

public class Main {

    private static Logger log = Logger.getLogger(Main.class);

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        PropertyConfigurator.configure("log4j.properties");
        log.warn("Test test test  ");
    }
}

另一次日食作为读者运行该程序。

public class Main {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        StringBuffer intiLine = new StringBuffer("");
        FileReader reader = new FileReader("D:\\logs\\notify-subscription.log");
        BufferedReader br = new BufferedReader(reader);
        String detail;
        while ((detail =br.readLine()) != null)//debug and set breakpoint here
        {
            System.out.println(detail);
        }
    }
}

在我开始测试它们之前。原始日志文件内容为空。 我首先运行了读者程序。 br.readLine()的结果应为null。但是我在代码行while ((detail =br.readLine()) != null)运行时设置了断点,在运行之前,我运行了编写器程序。因此该文件包含test test test。并且br.readLine()不会为空。

答案 2 :(得分:-1)

你绝对是正确的。如果你继续创建用于向文件写入内容的线程,那么Deadlock也有机会。因为如果线程继续写入文件那么就没有任何机会退出循环它会转到无限状态