이번 글에서는 NIO에 포함된 class 중에서 WatchService에 대해서 정리하고자 한다.
WatchService는 별도의 thread로 등록된 파일 혹은 디렉토리의 변경사항을 감지해서 이벤트로 리턴한다.
보안 모니터링 및 속성 파일 변경 등 여러 작업에 대한 알림 용도로 사용할 때 유용하다.
예제 코드를 통해서 자세히 살펴보자.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.nio.file.*; | |
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; | |
public class WatchServiceTest { | |
public static void main(String[] args) { | |
try { | |
WatchService watcher = FileSystems.getDefault().newWatchService(); | |
Path dir = FileSystems.getDefault().getPath("/usr/karianna"); | |
WatchKey key = dir.register(watcher, ENTRY_MODIFY); | |
while (true) { | |
key = watcher.take(); | |
for (WatchEvent<?> event : key.pollEvents()) { | |
if (event.kind() == ENTRY_MODIFY) { | |
System.out.println("Home dir changed!"); | |
} | |
} | |
key.reset(); | |
} | |
} catch (IOException | InterruptedException e) { | |
System.out.println(e.getMessage()); | |
} | |
} | |
} |
- WatchService는 FileSystem.newWatchService() 메서드를 통해 생성한다. 생성한 WatchSservice와 감지하고자 하는 종류(ENTRY_MODIFY - 수정)를 등록한다.
- 무한루프에서 감지를 한다.
- WathService의 take() 메서드로 변경사항이 발생한 WatchKey를 찾을 때까지 기다린다. WatchKey를 얻으면 WatchEvent를 가져온다.
- WatchEvent가 ENTRY_MODIFY인 것을 찾는다.
- key를 리셋한다.
위와 같은 과정을 무한히 반복하면서 등록된 파일 혹은 디렉토리를 감지한다.
이벤트의 다른 종류로서 ENTRY_CREATE, ENTRY_DELETE, OVERFLOW (잃거나 버려짐)
WatchService가 동작하는 방식이 궁금해서 추가적으로 구현체가 있는 PollingWatchService를 살펴보았다.
WatchService를 생성할 때 newSingleThreadScheduledExecutor로 새로운 Thread를 생성했다.
PollingWatchService() { // TBD: Make the number of threads configurable scheduledExecutor = Executors .newSingleThreadScheduledExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread t = new Thread(null, r, "FileSystemWatcher", 0, false); t.setDaemon(true); return t; }}); }
그리고 Thread는 감지하고자하는 디렉토리를 등록하는 register 함수를 호출할 때 시작했다.
감지는 10초 단위로 이루어졌다.
this.poller = scheduledExecutor .scheduleAtFixedRate(thunk, period, period, TimeUnit.SECONDS);
변경사항이 발생한 것을 확인해야 하기에 감지대상이 되는 파일들을 내부적으로 캐싱을 하고 있었다.
WatchService에 대한 추가적인 정보는 참고문서로 올려둔 자료를 참고하면 된다.
참고문서
반응형
'Language > Java' 카테고리의 다른 글
AtomicIntegerFieldUpdater (0) | 2023.04.08 |
---|---|
[multi thread] CountDownLatch (0) | 2020.06.04 |
[multi thread] Semaphore (0) | 2020.06.02 |
[Java9] Collections, Streams (0) | 2020.03.13 |
Proxy를 통한 Restful API 호출 by Java (0) | 2019.12.09 |