编辑2:我已经更新了WatcherService,并在一个同步块中包装了Path:
private void registerAll(final Path start) throws IOException {
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir,BasicFileAttributes attrs) throws IOException {
synchronized(dir){
logger.debug("Dir: " + dir.toString());
register(dir);
return FileVisitResult.CONTINUE;
}
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
synchronized(file){
logger.debug("File: " + file.getFileName());
//register(file);
file.toFile().setLastModified(DateTime.now().getMillis());
return FileVisitResult.CONTINUE;
}
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException e) {
synchronized(file){
logger.debug("Error visiting file {} with exception {}",file.toFile().getAbsolutePath(),e.getCause());
e.printStackTrace();
file.toFile().setLastModified(DateTime.now().getMillis());
return FileVisitResult.CONTINUE;
}
}
});
}
在class
下面 WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
}
Path dir = keys.get(key);
synchronized(dir){
if (dir == null) {
System.err.println("WatchKey not recognized!!");
continue;
}
// process file functionality: Add path to DB, etc
}
对方法的看法?与当前的实现相比,通道锁能为我提供什么好处?
我有两个线程。一个线程监视对目录的更改,并将这些更改写入数据库。第二个线程定期从数据库中读取文件路径,并将文件加载到内存中。当线程同时执行时,我遇到了一个问题。一个可能正在更新它的lastModified日期,而另一个则试图将其读入内存。
我不知道该采取哪种方法。我可以写一个同步块周围的引用文件,或者我需要获得一个读写锁,创建一个通道?
如果创建具有同步的通道会更好,因为它将正确地管理读和写,而且它比同步块更有效。此外,在文件处理的情况下,最好使用这个