为什么线程在另一个线程开始执行时会停止?
问题描述:
我是新来的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)停止,不看任何新的文件,直到副本完成了。为什么发生这种情况?我做错了什么,或者这不是正确的做法?
答
两个可能的答案出现在我的脑海中,我不能保证它们适用于您的具体情况: 1. Java VM从CPU中只获取一个核心,这意味着它一次只能运行一个线程。 2.您的线程都使用相同的变量,这意味着一次只允许一个变量进行真正的操作。对于这个特定的问题,查找java关键字“synchronized”。 我想问题的根源往往是#1
'dirThreads'和'threadsNumber'的值是什么? –
请注意,'dir!=“”'不会编译。 –
@AndyTurner _threadsNumber_是来自用户的输入,_dirThreads_是threadsNumber - 1.我手写完整,因为它不在同一台计算机上,这是我的错误dir!=“”。检查编辑后的问题。 –