我已经阅读了几个关于使用多线程读取文件的答案,并且发现它的效率非常差但仍然为了学习我试图使用多线程读取文件,即对于大文件,应该通过读取少量记录一个线程和另一个线程。
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class QueueThread implements Runnable {
int count=0;
private int start;
private int end;
public QueueThread(int start,int end) {
this.start=start;
this.end=end;
}
public void run() {
for(int i=start;i<end;i++) {
try {
Scanner read = new Scanner (new File("userinfo.txt"));
read.useDelimiter(",|\n");
String mobile,recharge;
while(read.hasNext())
{
mobile = read.next();
recharge =read.next();
ArrayList<String> words = new ArrayList<String>();
words.add(mobile+recharge);
count++;
System.out.println("mobile no.:"+ mobile);
System.out.println("recharge amount:"+ recharge);
System.out.println("count:"+ count );
}
read.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Control.java:
public class Control {
public static void main(String args[]) throws InterruptedException
{
QueueThread r1=new QueueThread(0,15);
QueueThread r2=new QueueThread(15,30);
Thread t1 =new Thread(r1);
Thread t2 =new Thread(r2);
t1.start();
t2.start();
t1.join();
t2.join();
}
}
这里我正在阅读一个文件userinfo.txt,其中包含一些随机的10位数字。和一些数字。每个线程读取整个文件,而不是只读取一个线程中的前15个条目和另一个线程中的其他14个条目,我认为这些条目违背了我并行阅读文件的座右铭。 我还试图将提取的数据存储在ArrayList中,以便对其执行进一步的操作。
userinfo.txt
9844794101,43
9844749102,54
9844741903,55
9844741094,33
9844741095,87
9844741068,32
9844974107,53
8848897101,343
8848891702,345
8848891063,34
8848849104,64
我真的需要一些出路来同时在不同的线程中读取文件
当前输出
mobile no.:9844794101
recharge amount:43
mobile no.:9844794101
count:1
recharge amount:43
count:1
mobile no.:9844749102
recharge amount:54
mobile no.:9844749102
recharge amount:54
count:2
count:2
等等
答案 0 :(得分:1)
如果是为了学习,那么只需使用两个线程的单个Scanner对象即可。由于您需要读取一对相邻的单词然后加入它们,您必须考虑一些解决方案如何使您的两个线程工作。
最简单的方法是允许每个线程使用&synchronized(scannerObject){...}读取几个单词。当然,性能会比单线程解决方案更差。其他解决方案可能会避免同步如果您使用AtomicInteger作为计数器并将ConcurrentSkipListMap中的单词从计数器存储到下一个单词。
我认为经典的方法是知道文件中间的精确点,您可以从中读取新单词。然后你的第一个线程会从一开始就读到一个文件中间的&#39;位置,第二个线程可以从中间读取#39;位置到最后。参见例如Webkit, Gecko and in latest Microsoft browsers
答案 1 :(得分:0)
而不是
Scanner read = new Scanner (new File("userinfo.txt"));
你需要使用像
这样的东西InputStream inputStream = new BufferedInputStream(new FileInputStream(new File("userinfo.txt"))));
inputStream.skip(<number of bytes to start of first desired record>);
Scanner read = new Scanner(inputStream);
// then make sure you only read as many records as you need
搜索有关InputStream
和Reader
s。
问题是,根据你的记录格式,如果没有读取文件的前一部分,就无法获得skip
的正确参数(尽管你只需要查找换行符,而不是{{1} }或,
)。您可以使|
和start
个字节数而不是记录数,但是您需要知道您可能会在记录中间着陆并小心。
此外,如果您希望最终的end
按顺序排列,那么第二个线程将必须等到第一个线程完成插入。如果您不这样做,请确保同步对其的访问权限或改为使用The suggestion by Mr. Bugle。