使用java线程实现的生产者-消费者只将一半的数据写入文件
你好,我有一个问题,我必须阅读一个巨大的csv文件。从中删除第一个字段,然后仅将唯一值存储到文件中。我已经用线程编写了一个程序,它实现了生产者-消费者模式 类CSVLineStripper执行名称所示的操作。从csv中取出一行,从每行中删除第一个字段并将其添加到队列中。CSVLineProcessor然后将该字段逐个存储在arraylist中,并检查字段是否唯一,以便只存储唯一字段。Arraylist仅供参考。每个唯一字段都写入一个文件 现在发生的是所有字段都被正确剥离。我跑了3000行,都对了。当我为所有行启动程序时,大约有700000多行,我得到了不完整的记录,大约1000个唯一的记录没有被获取。每个字段都用双引号括起来。奇怪的是,生成的文件中的最后一个字段是一个不完整的单词,并且缺少结尾的双引号。为什么会这样使用java线程实现的生产者-消费者只将一半的数据写入文件,java,multithreading,Java,Multithreading,你好,我有一个问题,我必须阅读一个巨大的csv文件。从中删除第一个字段,然后仅将唯一值存储到文件中。我已经用线程编写了一个程序,它实现了生产者-消费者模式 类CSVLineStripper执行名称所示的操作。从csv中取出一行,从每行中删除第一个字段并将其添加到队列中。CSVLineProcessor然后将该字段逐个存储在arraylist中,并检查字段是否唯一,以便只存储唯一字段。Arraylist仅供参考。每个唯一字段都写入一个文件 现在发生的是所有字段都被正确剥离。我跑了3000行,都对了
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