EDIT 2: I've updated my WatcherService and wrapped the Path within a synchronized block:
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;
}
}
});
}
Further down in 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
}
Thoughts on approach? What benefit would a channel lock provide for me vs the current implementation?
EDIT: Do I need to have the locks on both threads or just one?
I have two threads. One thread watches for changes to a directory and writes those changes to a DB. The second thread periodically reads the file paths from the database and loads the files into memory. I am running into an issue when the threads are executing at the same time. One is possibly updating its lastModified date while the other is trying to read it into memory.
I'm confused as to which approach I should take. Can I write a synchronization block around the reference to the file or do I need to acquire a readWrite lock, create a channel?