-2

My threads all become null for some reason within my run method so i get a nullpointerexception when I try to interrupt them at the end? I know they are becoming null within the run method because I i did a lot of system.out.printin's and my print within the run prints once only.

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);
                                        }                   
        }
    }
   }
  • 1
    I don't see any place that you actually populated `workers` with anything. Also, I think your lack of indentation is hiding the triple-nesting of your for-loops. Why are trying to interrupt all your threads each time you try to create one? – azurefrog Nov 22 '16 at 19:31
  • As azurefrog said, you do not assign `workers` in the foreach loop. You should use a standard `for` loop. See [How does the Java for each loop work?](https://stackoverflow.com/questions/85190/how-does-the-java-for-each-loop-work) for more info on the java `foreach`. – jrbeverly Nov 22 '16 at 19:38

1 Answers1

0
    for(Thread w:workers){ //start all the worker threads
        w = new Thread(newWorker);
        w.start();

For each thread in workers, you create a new thread?

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 1
    While its simply wrong to do this, thats not actually whats causing the issue. A Thread *is* a Runnable and can be misused as such. Would be better placed as a comment. – Durandal Nov 22 '16 at 19:33
  • I understood his question to be asking why he couldn't interrupt the threads he started, and the answer is this. He's trying to interrupt the threads in `workers`, and those aren't the threads he started. – David Schwartz Nov 22 '16 at 19:47
  • But the immediate reason why he gets an exception is that his array is full of nulls, which you don't touch upon. For an answer I'd expect at least to mention that. – Durandal Nov 22 '16 at 20:08
  • @Durandal That's the immediate reason, but it's the natural consequence of the error I indicated. Fixing the error I indicated will make that reason go away. Pointing out the immediate reason, rather than the earlier mistake that caused it, would have been less helpful. If he fixes this mistake, that later code will work correctly with no changes to it -- that code is not the problem, it's the code I pointed out that's the problem. He needs to fix the perpetrator, not the victim. (He probably got stuck because he kept looking at the victim code.) – David Schwartz Nov 22 '16 at 20:10