我正在尝试将多线程与FileWatcher服务集成在java中。即,我一直在听一个特定的目录 - >每当创建一个新文件时,我需要生成一个处理该文件的新线程(比如它打印文件内容)。我设法编写了一个编译和工作的代码(但不是预期的)。它按顺序工作意味着file2在file1之后处理,而文件3在文件2之后处理。我希望它并行执行。
添加代码段:
while(true) {
WatchKey key;
try {
key = watcher.take();
Path dir = keys.get(key);
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
if(kind == StandardWatchEventKinds.ENTRY_CREATE){
boolean valid = key.reset();
if (!valid) {
break;
}
log.info("New entry is created in the listening directory, Calling the FileProcessor");
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path newFileCreatedResolved = dir.resolve(ev.context());
try{
FileProcessor processFile = new FileProcessor(newFileCreatedResolved.getFileName().toString());
Future<String> result = executor.submit(processFile);
try {
System.out.println("Processed File" + result.get());
} catch (ExecutionException e) {
e.printStackTrace();
}
//executor.shutdown(); add logic to shut down
}
}
}
}
}
和FileProcessor类
public class FileProcessor implements Callable <String>{
FileProcessor(String triggerFile) throws FileNotFoundException, IOException{
this.triggerFile = triggerFile;
}
public String call() throws Exception{
//logic to write to another file, this new file is specific to the input file
//returns success
}
现在发生了什么 - &gt;如果我一次传输3个文件,它们是顺序的。第一个file1写入其目标文件,然后是file2,file3等。
我有道理吗?我需要改变哪个部分才能使其平行?或者Executor服务的设计就是这样。
答案 0 :(得分:0)
对Future.get()
的调用正在阻止。当然,在处理完成之前,结果是不可用的,并且您的代码在此之前不会提交其他任务。
将Executor
CompletionService
和submit()
任务包裹在其中。让另一个线程使用CompletionService
的结果来完成任务完成后所需的任何处理。
或者,您可以使用CompletableFuture
的辅助方法来设置等效的操作管道。
第三种,更简单但可能不太灵活的选项只是将后处理结合到任务本身中。我demonstrated是一个简单的任务包装器,用于说明如何完成此任务。