java多线程读取文件夹中的多个文件问题,新手多谢!
现在想利用多线程读取一个文件夹中的多个xml文件,但是现在每个线程都把所有文件全部读一遍,我希望的是一个线程读过的文件,其他线程就不去读了,请问我的代码错在什么地方?本人新手,多谢!
ps:我也试过每读一个文件就把它从列表里删除,还是不行。。
package comparison;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
public class CompareTest {
public static void main(String args[]){
read read = new read();
new Thread(read, "线程1").start();
new Thread(read, "线程2").start();
new Thread(read, "线程3").start();
new Thread(read, "线程4").start();
new Thread(read, "线程5").start();
//List list = read.readXML();
//for(String s:list){
//System.out.println(s);
//}
}
}
class read implements Runnable{
@Override
public void run() {
File f = new File("d:"+File.separator+"comparetest");
File[] filePaths = f.listFiles();
List filePathsList = new ArrayList<>();
for(File s:filePaths){
filePathsList.add(s);
}
//解析xml
SAXBuilder builder = new SAXBuilder();
List xmlList = new ArrayList<>();
for(int i=0;i
synchronized(this){
try {
Thread.sleep(300);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
InputStream is = new FileInputStream(filePathsList.get(i));
System.out.println("当前使用的线程是:"+Thread.currentThread().getName()+",正在读文件:"+filePathsList.get(i)+",列表当前长度:"+filePathsList.size());
Document doc = builder.build(is);
Element root = doc.getRootElement();
List list = root.getChildren();
for(Element e:list){
xmlList.add(e.getChildTextTrim("ERROR_FEEDBACK_ID"));
}
xmlList.add("--------------------------");
} catch (JDOMException | IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
//public synchronized List readXML(){
//
}
//return xmlList;
//}
}
------解决方案--------------------
new Thread(read, "线程1").start();
new Thread(read, "线程2").start();
new Thread(read, "线程3").start();
new Thread(read, "线程4").start();
new Thread(read, "线程5").start();
这几个线程执行顺序我们是无法控制的,线程并发也是无法避免的。要实现你的功能那就只有一个办法让这5个线程之间有一个共识,就是让他们都知道除他之外的线程是否已经对某个文件进行了读取操作,如果已读取就不再读了。这就要用到线程之间的通信来完在。这里最好的办法就是定义一个全局变量,当一个线程一开始读取文件就把这个文件名信息存入这个全局变量中,别的线程读取时来判断一下那文件是否己经存到了全局变量中,如果已存在就不在讯取这个文件了。大体思路是这样的。所以你这个代码就得改一下在main中建一个全局变量LIST,然后把这个LIST传进这5个线程中来达到效果,当然也可以把list设成static这个好做一些。需要注意的是在每个线程中需要给这个全局的list加上线程锁,当任意一个线程对list进行操作时,让其他线程都处理等待状态。
------解决方案--------------------
上面代码还有个小bug,如下是在你基础上进行最小改动的
public class CompareTest {
public static void main(String args[]) {
read read = new read();
new Thread(read, "线程1").start();
new Thread(read, "线程2").start();
new Thread(read, "线程3").start();
new Thread(read, "线程4").start();
new Thread(read, "线程5").start();
}
}
class read implements Runnable {
List filePathsList = new ArrayList();
int index = 0;
public read() {
File f = new File("d:" + File.separator + "tmp");
getFileList(f);
}
private void getFileList(File f) {
File[] filePaths = f.listFiles();
for (File s : filePaths) {
if (s.isDirectory()) {
getFileList(s);
} else {
if (-1 != s.getName().lastIndexOf(".xml")) {
filePathsList.add(s);
}
}
}
}
@Override
public void run() {
File file = null;
while (index
synchronized (this) {
if (index >= filePathsList.size()) {
continue;
}
file = filePathsList.get(index);
index++;
}
// 解析xml
SAXBuilder builder = new SAXBuilder();
List xmlList = new ArrayList();