我是Java并发API的新手,我已经搜索过,但没有找到我的问题的答案。
好吧,我有一个代码可以查找目录及其子目录中的每个文件,另一个代码可以复制每个匹配指定模式的文件。
我在一个名为 DirSearch 的 Runnable 实现和一个名为 FileSearch 的 Callable 实现中分离这些代码并提交它们使用 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 )会停止,并且在复制完成之前不会查找任何新文件。为什么会这样?我做错了什么或者这不是正确的方法吗?
答案 0 :(得分:-1)
我想到了两个可能的答案,我不能保证它们适用于您的具体情况: 1. Java VM只从CPU获取一个核心,这意味着它一次只能运行一个线程。 2.你的线程都使用相同的变量,这意味着一次只允许一个人真正操作它。对于此特定问题,请查找java关键字“synchronized”。 我想问题的根源往往是#1