【发布时间】:2016-11-22 19:24:46
【问题描述】:
由于某种原因,我的线程在我的运行方法中全部变为空,所以当我尝试在最后中断它们时得到一个空指针异常?我知道它们在运行方法中变为空,因为我做了很多 system.out.printin 和我在运行中的打印只打印一次。
import java.io.* ;
import java.lang.*;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.regex.Pattern;
public class fileCrawler {
private static class worker implements Runnable{
private Pattern p;
private PriorityBlockingQueue<String> pbq;
private ConcurrentSkipListSet<String> csls;
public worker(Pattern pattern, PriorityBlockingQueue<String> inputPBQ, ConcurrentSkipListSet<String> inputCSLS){
this.p = pattern;
this.pbq = inputPBQ;
this.csls = inputCSLS;
}
public synchronized void parseFiles(File dir){
File[] contents = dir.listFiles();
for(File item:contents){
if(item.isFile()){
if(item.getName().compareTo(p.toString())==0){
csls.add(item.getAbsolutePath().toString());
}
}
else if(item.isDirectory()){
pbq.add(item.getName());
parseFiles(item);
}
}
}
public void run(){
while(!pbq.isEmpty()){
File openFile;
System.out.println(p);
openFile = new File(pbq.poll());
parseFiles(openFile);
}
}
}
public static String regexPatGen(String bashPat){
StringBuilder regexPat = new StringBuilder();
regexPat.append("^");
for(int i = 0;i<bashPat.length();i++){
switch(bashPat.charAt(i)){
case '*':
regexPat.append(".*");
break;
case '.':
regexPat.append("\\.");
break;
case '?':
regexPat.append(".");
break;
default:
regexPat.append(bashPat.charAt(i));
break;
//call main to fill work queue with list of directories
}
}
regexPat.append("$");
String a;
a = regexPat.toString();
return a;
}
public static void main(String Arg[]){
int threadNum;
PriorityBlockingQueue<String> dirList = new PriorityBlockingQueue<String>();
ConcurrentSkipListSet<String> fileList = new ConcurrentSkipListSet<String>();
if(System.getenv("CRAWLER_THREADS")!=null){
threadNum = Integer.parseInt(System.getenv("CRAWLER_THREADS"));
}
else{
threadNum = 5;
}
String temp = regexPatGen(Arg[0]);
Pattern pattern = Pattern.compile(temp);
Thread workers[] = new Thread[threadNum]; //create array of threads
worker newWorker = new worker(pattern,dirList,fileList);
if(Arg.length==1){ //call main to fill work queue with list of directories
dirList.add(".");}
else{
for(int i = 1;i<Arg.length;i++){
dirList.add(Arg[i]); }
}
for(Thread w:workers){ //start all the worker threads
w = new Thread(newWorker);
w.start();
for(int i = 0; i<workers.length;i++){
workers[i].interrupt();
try {
workers[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(String fileName:fileList){
System.out.println(fileName);
}
}
}
}
【问题讨论】:
-
我没有看到您在
workers上实际填充了任何东西。另外,我认为您缺少缩进隐藏了 for 循环的三重嵌套。为什么每次尝试创建线程时都尝试中断所有线程? -
正如 azurefrog 所说,您没有在 foreach 循环中分配
workers。您应该使用标准的for循环。有关 javaforeach的更多信息,请参阅 How does the Java for each loop work?。
标签: java multithreading thread-safety