Watcher Class — netty Architecture
Architecture documentation for the Watcher class in ThreadDeathWatcher.java from the netty codebase.
Entity Profile
Dependency Diagram
graph TD 5f6d0707_3005_8256_7c2d_19661826552d["Watcher"] e4597d51_0c3d_f1d3_89b7_46f963dc242f["ThreadDeathWatcher.java"] 5f6d0707_3005_8256_7c2d_19661826552d -->|defined in| e4597d51_0c3d_f1d3_89b7_46f963dc242f 2e12d8f3_2a76_c115_2e1f_27af3c853d54["run()"] 5f6d0707_3005_8256_7c2d_19661826552d -->|method| 2e12d8f3_2a76_c115_2e1f_27af3c853d54 d63c9c90_1e42_7586_aab0_7f19f87736ba["fetchWatchees()"] 5f6d0707_3005_8256_7c2d_19661826552d -->|method| d63c9c90_1e42_7586_aab0_7f19f87736ba 666cccad_fc12_bc19_59b3_051276b803c6["notifyWatchees()"] 5f6d0707_3005_8256_7c2d_19661826552d -->|method| 666cccad_fc12_bc19_59b3_051276b803c6
Relationship Graph
Source Code
common/src/main/java/io/netty/util/ThreadDeathWatcher.java lines 146–228
private static final class Watcher implements Runnable {
private final List<Entry> watchees = new ArrayList<Entry>();
@Override
public void run() {
for (;;) {
fetchWatchees();
notifyWatchees();
// Try once again just in case notifyWatchees() triggered watch() or unwatch().
fetchWatchees();
notifyWatchees();
try {
Thread.sleep(1000);
} catch (InterruptedException ignore) {
// Ignore the interrupt; do not terminate until all tasks are run.
}
if (watchees.isEmpty() && pendingEntries.isEmpty()) {
// Mark the current worker thread as stopped.
// The following CAS must always success and must be uncontended,
// because only one watcher thread should be running at the same time.
boolean stopped = started.compareAndSet(true, false);
assert stopped;
// Check if there are pending entries added by watch() while we do CAS above.
if (pendingEntries.isEmpty()) {
// A) watch() was not invoked and thus there's nothing to handle
// -> safe to terminate because there's nothing left to do
// B) a new watcher thread started and handled them all
// -> safe to terminate the new watcher thread will take care the rest
break;
}
// There are pending entries again, added by watch()
if (!started.compareAndSet(false, true)) {
// watch() started a new watcher thread and set 'started' to true.
// -> terminate this thread so that the new watcher reads from pendingEntries exclusively.
break;
}
// watch() added an entry, but this worker was faster to set 'started' to true.
// i.e. a new watcher thread was not started
// -> keep this thread alive to handle the newly added entries.
}
}
}
private void fetchWatchees() {
for (;;) {
Entry e = pendingEntries.poll();
if (e == null) {
break;
}
if (e.isWatch) {
watchees.add(e);
} else {
watchees.remove(e);
}
}
}
private void notifyWatchees() {
List<Entry> watchees = this.watchees;
for (int i = 0; i < watchees.size();) {
Entry e = watchees.get(i);
if (!e.thread.isAlive()) {
watchees.remove(i);
try {
e.task.run();
} catch (Throwable t) {
logger.warn("Thread death watcher task raised an exception:", t);
}
} else {
i ++;
}
}
Source
Frequently Asked Questions
What is the Watcher class?
Watcher is a class in the netty codebase, defined in common/src/main/java/io/netty/util/ThreadDeathWatcher.java.
Where is Watcher defined?
Watcher is defined in common/src/main/java/io/netty/util/ThreadDeathWatcher.java at line 146.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free