从同一文件/奇数行为读取的多个线程

时间:2014-03-28 03:16:12

标签: java multithreading

我正在编写一个需要从非常大的文件(400K +行)读取行的程序,并将每行中的数据发送到Web服务。我决定尝试线程,并且看到了一些我没想到的行为,看起来我的BufferedReader开始重用它在我调用readline()时已经给我的行。

我的课程由两个班级组成。 A" Main"启动线程并保存对BufferedReader的静态引用并具有静态同步" readNextLine()"线程可以用来基本上调用BufferedReder上的readLine()的方法。 " Runnable"调用readNextLine()并使用每个readNextLine()调用的数据进行webservice调用的类。我将BufferedReader和readNextLine()设为静态只是因为除了将主类的实例传递给线程之外,这是我能想到线程共享读者的唯一方法,我不确定哪个更好。

大约5分钟后,我开始在网络服务中看到错误,说它正在处理已经处理过的行。我能够验证线路确实被多次发送,相隔几分钟。

有没有人有任何想法为什么BufferedReader似乎给它已读取的线程行?我的印象是readline()是顺序的,我需要做的就是确保对readline()的调用是同步的。

我将在下面展示一些Main类代码。 runnable本质上是一个while循环,它调用readNextLine()并处理每一行,直到没有剩余的行为止。

主要课程:

 //showing reader and thread creation
 inputStream = sftp.get(path to file);
 reader = new BufferedReader(new InputStreamReader(inputStream));

 ExecutorService executor = Executors.newFixedThreadPool(threads);
        Collection<Future> futures = new ArrayList<Future>();
        for(int i=0;i<threads;i++){
        MyRunnable runnable = new   MyRunnable(i);
            futures.add(executor.submit(runnable));
        }
        LOGGER.debug("futures.get()");
        for(Future f:futures){
            f.get();  //use to wait until all threads are done 
        }

public synchronized static String readNextLine(){
    String results = null;
    try{
        if(reader!=null){
         results = reader.readLine();
        }
    }catch(Exception e){
        LOGGER.error("Error reading from file");
    }

    return results;
}

1 个答案:

答案 0 :(得分:0)

我正在测试你所说的内容,但我发现你在readNextLine()方法中得到了一个错误逻辑,如何调用reader.readLine(),因为结果是null而if条件是不是空?

现在我完成了我的演示,看起来效果很好,以下是演示,没有重读线:

 static BufferedReader reader;

public static void main(String[] args) throws FileNotFoundException, ExecutionException, InterruptedException {
    reader = new BufferedReader(new FileReader("test.txt"));
    ExecutorService service = Executors.newFixedThreadPool(3);
    List<Future> results = new ArrayList<Future>();
    for (int i = 0; i < 3; i++) {
        results.add(service.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    String line = null;
                    while ((line = readNextLine()) != null) {
                        System.out.println(line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }));
    }
}

public synchronized static String readNextLine() throws IOException {
    return reader.readLine();
}
相关问题