【问题标题】:Java multithreading, my threads are all become nullified within the run methodJava多线程,我的线程都在run方法中失效
【发布时间】: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 循环。有关 java foreach 的更多信息,请参阅 How does the Java for each loop work?

标签: java multithreading thread-safety


【解决方案1】:
    for(Thread w:workers){ //start all the worker threads
        w = new Thread(newWorker);
        w.start();

对于workers中的每个线程,你创建一个新线程吗?

【讨论】:

  • 虽然这样做完全是错误的,但实际上并不是导致问题的原因。线程 is 是可运行的,因此可能会被滥用。最好放在评论中。
  • 我理解他的问题是问他为什么不能中断他开始的线程,答案是这样的。他试图中断workers 中的线程,而那些不是他启动的线程。
  • 但是他得到异常的直接原因是他的数组充满了空值,你没有触及。对于一个答案,我希望至少提到这一点。
  • @Durandal 这是直接原因,但这是我指出的错误的自然结果。修复我指出的错误将使该原因消失。指出直接原因,而不是导致它的早期错误,将没有多大帮助。如果他修正了这个错误,那么后面的代码将在不做任何更改的情况下正常工作——那个代码不是问题,而是我指出的代码才是问题所在。他需要修复肇事者,而不是受害者。 (他可能被卡住了,因为他一直在查看受害者代码。)
猜你喜欢
  • 2011-03-03
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 1970-01-01
相关资源
最近更新 更多