使用java线程实现的生产者-消费者只将一半的数据写入文件

使用java线程实现的生产者-消费者只将一半的数据写入文件,java,multithreading,Java,Multithreading,你好,我有一个问题,我必须阅读一个巨大的csv文件。从中删除第一个字段,然后仅将唯一值存储到文件中。我已经用线程编写了一个程序,它实现了生产者-消费者模式 类CSVLineStripper执行名称所示的操作。从csv中取出一行,从每行中删除第一个字段并将其添加到队列中。CSVLineProcessor然后将该字段逐个存储在arraylist中,并检查字段是否唯一,以便只存储唯一字段。Arraylist仅供参考。每个唯一字段都写入一个文件 现在发生的是所有字段都被正确剥离。我跑了3000行,都对了

你好,我有一个问题,我必须阅读一个巨大的csv文件。从中删除第一个字段,然后仅将唯一值存储到文件中。我已经用线程编写了一个程序,它实现了生产者-消费者模式

类CSVLineStripper执行名称所示的操作。从csv中取出一行,从每行中删除第一个字段并将其添加到队列中。CSVLineProcessor然后将该字段逐个存储在arraylist中,并检查字段是否唯一,以便只存储唯一字段。Arraylist仅供参考。每个唯一字段都写入一个文件

现在发生的是所有字段都被正确剥离。我跑了3000行,都对了。当我为所有行启动程序时,大约有700000多行,我得到了不完整的记录,大约1000个唯一的记录没有被获取。每个字段都用双引号括起来。奇怪的是,生成的文件中的最后一个字段是一个不完整的单词,并且缺少结尾的双引号。为什么会这样

import java.util.*;
import java.io.*;
class CSVData
{
    Queue <String> refererHosts = new LinkedList <String> ();
    Queue <String> uniqueReferers = new LinkedList <String> (); // final writable queue of unique referers

    private int finished = 0;
    private int safety = 100;
    private String line = "";
    public CSVData(){}
    public synchronized String getCSVLine() throws InterruptedException{
        int i = 0;
        while(refererHosts.isEmpty()){
            if(i < safety){
                wait(10);
            }else{
                return null;
            }
            i++;
        }
        finished = 0;
        line = refererHosts.poll();
        return line;
    }

    public synchronized void putCSVLine(String CSVLine){
        if(finished == 0){ 
            refererHosts.add(CSVLine);
            this.notifyAll();
        }
    }
}
class CSVLineStripper implements Runnable //Producer
{
    private CSVData cd;
    private BufferedReader csv;
    public CSVLineStripper(CSVData cd, BufferedReader csv){ // CONSTRUCTOR
        this.cd = cd;
        this.csv = csv;
    }
    public void run() {
        System.out.println("Producer running");
        String line = "";
        String referer = "";
        String [] CSVLineFields;
        int limit = 700000;
        int lineCount = 1;

        try {
            while((line = csv.readLine()) != null){
                CSVLineFields     = line.split(",");
                referer         = CSVLineFields[0];
                cd.putCSVLine(referer);
                lineCount++;
                if(lineCount >= limit){
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("<<<<<< PRODUCER FINISHED >>>>>>>");
    }

    private String printString(String [] str){
        String string = "";
        for(String s: str){
            string = string + " "+s;
        }
        return string;
    }
}

class CSVLineProcessor implements Runnable
{
    private CSVData cd;
    private FileWriter fw = null;
    private BufferedWriter bw = null;

    public CSVLineProcessor(CSVData cd, BufferedReader bufferedReader){ // CONSTRUCTOR
        this.cd = cd;
        try {
            this.fw = new FileWriter("unique_referer_dump.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.bw = new BufferedWriter(fw);
    }
    public void run() {
        System.out.println("Consumer Started");
        String CSVLine = "";
        int safety = 10000;
        ArrayList <String> list = new ArrayList <String> ();

        while(CSVLine != null || safety <= 10000){
               try {
                CSVLine = cd.getCSVLine();
                if(!list.contains(CSVLine)){
                    list.add(CSVLine);
                    this.CSVDataWriter(CSVLine);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(CSVLine == null){
                break;
            }else{
                safety++;
            }
        }

        System.out.println("<<<<<< CONSUMER FINISHED >>>>>>>");
        System.out.println("Unique referers found in 30000 records "+list.size());
    }  
    private void CSVDataWriter(String referer){
        try {
            bw.write(referer+"\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


public class RefererCheck2 
{
    public static void main(String [] args) throws InterruptedException
    {
        String pathToCSV = "/home/shantanu/DEV_DOCS/Contextual_Work/excite_domain_kw_site_wise_click_rev2.csv";
        CSVResourceHandler csvResHandler = new CSVResourceHandler(pathToCSV);
        CSVData cd = new CSVData();
        CSVLineProcessor consumer     = new CSVLineProcessor(cd, csvResHandler.getCSVFileHandler());
        CSVLineStripper producer     = new CSVLineStripper(cd, csvResHandler.getCSVFileHandler());
        Thread consumerThread = new Thread(consumer);
        Thread producerThread = new Thread(producer);
        producerThread.start();
        consumerThread.start();
    }
}
排队的生产商商店:

"xyz.abc.com"
"pqr.stu.com"
"0.stu.com"
"m.dash.com"
消费者将Unique存储在文件中,但打开文件内容后会看到

"xyz.abc.com"
"pqr.stu.com"
"0.st

两件事,你在700k后崩溃,而不是7m,你也没有刷新你的缓冲写入程序,所以最后的东西可能是不完整的,在末尾添加刷新并关闭所有资源。调试器是一个好主意:)

两件事,700k后会中断,而不是7m,而且不会刷新缓冲写入程序,因此最后一件事情可能不完整,请在末尾添加刷新并关闭所有资源。调试器是个好主意:)

您是否尝试过在调试器中运行此功能?这是通常的出发点。也,编辑您的帖子,添加一些错误输出和相应输入的示例。旁注:使用集合检查重复项将比使用列表更有效#contains@JimGarrison:在某些650000行上发生错误时,使用步进步出进行调试?调试器具有条件断点,可在重复后触发计数。@JimGarrison请查看编辑后的示例输出文章您是否尝试在调试器中运行此功能?这是通常的出发点。也,编辑您的帖子,添加一些错误输出和相应输入的示例。旁注:使用集合检查重复项将比使用列表更有效#contains@JimGarrison:在某些650000行上发生错误时,使用步进步出进行调试?调试器具有条件断点,可在重复后触发计数。@JimGarrison请查看编辑后的文章以获取样本输出,这简直是愚蠢透顶!!!是的,我没有刷新缓冲写入程序。它起了神奇的作用。感谢700万,这是一个彻头彻尾的愚蠢!!!是的,我没有刷新缓冲写入程序。它起了神奇的作用。非常感谢
"xyz.abc.com"
"pqr.stu.com"
"0.st