2016-07-14 70 views
2

我是新来的Java并发API,我已经搜索,但没有找到我的问题的答案。为什么线程在另一个线程开始执行时会停止?

那么,我有一个代码,查找目录及其子目录中的每个文件,另一个代码复制匹配指定模式的每个找到的文件。

我在一个Runnable的实施这分开的代码称为DirSearch和一个可赎回实现调用FileSearch和使用ExecutorService的提交。

这是代码:

private boolean execute() { 
    ExecutorService executor = Executors.newFixedThreadPool(threadsNumber); 
    BlockingQueue<File> dirQueue = new LinkedBlockingQueue<>(); 
    BlockingQueue<File> fileQueue = new LinkedBlockingQueue<>(10000); 

    boolean isFinished = false; 

    try { 
     for(int i = 0; i < dirThreads; i++) { 
      executor.submit(new DirSearch(dirQueue, fileQueue, count, dirThreads); 
     } 

     count.incrementAndGet(); 
     dirQueue.add(baseDir); 

     Future<Boolean> future = executor.submit(new FileSearch(filequeue, outputDirectory, filename)); 

     isFinished = future.get(); 
    } catch(ExecutionException | InterruptedException | RuntimeException ex) { 
     ex.printStackTrace(); 
    } finally { 
     executor.shutdownNow(); 
    } 

    return isFinished; 
} 

... 

private void copyFile(File in, File out) { 
    Path inPath = Paths.get(in.getAbsolutePath()); 
    Path outPath = Paths.get(out.getAbsolutePath(), in.getName()); 

    try { 
     main.updateCurrentLabel(outPath.toString()); 

     switch(mode) { 
      case "1": 
       Files.copy(inPath, outPath, StandardCopyOption.REPLACE_EXISTING); 
       break; 
      case "2": 
       Files.move(inPath, outPath, StandardCopyOption.REPLACE_EXISTING); 
       break; 
      default: 
       break; 
     } 

     main.updateCopiedLabel(String.valueOf(countCpFiles.incrementAndGet())); 
    } catch(IOException ex) { 
     ex.printStackTrace(); 
    } 
} 

... 

private class DirSearch implements Runnable { 

    ... 

    @Override 
    public void run() { 
     try { 
      File dir = dirQueue.take(); 

      while(dir != new File("")) { 
       File[] elements = dir.listFiles(); 

       if(elements != null) { 
        for(File element : elements) { 
         if(element.isDirectory()) { 
          count.incrementAndGet(); 
          dirQueue.put(element); 
         } else { 
          fileQueue.put(element); 
         } 
        } 
       } 

       if(count.decrementAndGet() == 0) { 
        end(); 
       } 

       dir = dirQueue.take(); 
      } 
     } catch(InterruptedException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    ... 

} 

... 

private class FileSearch implements Callable<Boolean> { 

    ... 

    @Override 
    public Boolean call() { 
     boolean isFinished = false; 

     try { 
      File file = fileQueue.take(); 

      while(file != new File("")) { 
       incrementAnalyzed(); 
       String foundFile = file.getName().toLowerCase(); 

       if(foundFile.matches(filename.replace("?", ".?").replace("*", ".*?"))) { 
        copyFile(file, outputDirectory); 
       } 

       file = fileQueue.take(); 
      } 

      isFinished = true; 
     } catch(InterruptedException ex) { 
      ex.printStackTrace(); 
     } 

     return isFinished; 
    } 
} 

的问题是:当FileSearch开始复制文件,其他线程(DirSearch)停止,不看任何新的文件,直到副本完成了。为什么发生这种情况?我做错了什么,或者这不是正确的做法?

+3

'dirThreads'和'threadsNumber'的值是什么? –

+0

请注意,'dir!=“”'不会编译。 –

+0

@AndyTurner _threadsNumber_是来自用户的输入,_dirThreads_是threadsNumber - 1.我手写完整,因为它不在同一台计算机上,这是我的错误dir!=“”。检查编辑后的问题。 –

回答

-1

两个可能的答案出现在我的脑海中,我不能保证它们适用于您的具体情况: 1. Java VM从CPU中只获取一个核心,这意味着它一次只能运行一个线程。 2.您的线程都使用相同的变量,这意味着一次只允许一个变量进行真正的操作。对于这个特定的问题,查找java关键字“synchronized”。 我想问题的根源往往是#1