Home / Class/ ThreadDeathWatcher Class — netty Architecture

ThreadDeathWatcher Class — netty Architecture

Architecture documentation for the ThreadDeathWatcher class in ThreadDeathWatcher.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  a874767f_1376_f502_6409_38219e3d70ef["ThreadDeathWatcher"]
  e4597d51_0c3d_f1d3_89b7_46f963dc242f["ThreadDeathWatcher.java"]
  a874767f_1376_f502_6409_38219e3d70ef -->|defined in| e4597d51_0c3d_f1d3_89b7_46f963dc242f
  d0ccf1bb_8ca7_fdeb_a3d1_eecc0fd357d4["watch()"]
  a874767f_1376_f502_6409_38219e3d70ef -->|method| d0ccf1bb_8ca7_fdeb_a3d1_eecc0fd357d4
  bcd89545_0ae1_7935_4b1c_1e03947be6b7["unwatch()"]
  a874767f_1376_f502_6409_38219e3d70ef -->|method| bcd89545_0ae1_7935_4b1c_1e03947be6b7
  52d983df_3c33_cc34_17dc_62af3798f3ef["schedule()"]
  a874767f_1376_f502_6409_38219e3d70ef -->|method| 52d983df_3c33_cc34_17dc_62af3798f3ef
  2b4a6301_5512_d4d4_73a0_ea75ac4b9d8f["awaitInactivity()"]
  a874767f_1376_f502_6409_38219e3d70ef -->|method| 2b4a6301_5512_d4d4_73a0_ea75ac4b9d8f
  a59f6f0d_2725_c67d_9246_bb5b4d321774["ThreadDeathWatcher()"]
  a874767f_1376_f502_6409_38219e3d70ef -->|method| a59f6f0d_2725_c67d_9246_bb5b4d321774

Relationship Graph

Source Code

common/src/main/java/io/netty/util/ThreadDeathWatcher.java lines 46–260

@Deprecated
public final class ThreadDeathWatcher {

    private static final InternalLogger logger = InternalLoggerFactory.getInstance(ThreadDeathWatcher.class);
    // visible for testing
    static final ThreadFactory threadFactory;

    // Use a MPMC queue as we may end up checking isEmpty() from multiple threads which may not be allowed to do
    // concurrently depending on the implementation of it in a MPSC queue.
    private static final Queue<Entry> pendingEntries = new ConcurrentLinkedQueue<Entry>();
    private static final Watcher watcher = new Watcher();
    private static final AtomicBoolean started = new AtomicBoolean();
    private static volatile Thread watcherThread;

    static {
        String poolName = "threadDeathWatcher";
        String serviceThreadPrefix = SystemPropertyUtil.get("io.netty.serviceThreadPrefix");
        if (!StringUtil.isNullOrEmpty(serviceThreadPrefix)) {
            poolName = serviceThreadPrefix + poolName;
        }
        // because the ThreadDeathWatcher is a singleton, tasks submitted to it can come from arbitrary threads and
        // this can trigger the creation of a thread from arbitrary thread groups; for this reason, the thread factory
        // must not be sticky about its thread group
        threadFactory = new DefaultThreadFactory(poolName, true, Thread.MIN_PRIORITY, null);
    }

    /**
     * Schedules the specified {@code task} to run when the specified {@code thread} dies.
     *
     * @param thread the {@link Thread} to watch
     * @param task the {@link Runnable} to run when the {@code thread} dies
     *
     * @throws IllegalArgumentException if the specified {@code thread} is not alive
     */
    public static void watch(Thread thread, Runnable task) {
        ObjectUtil.checkNotNull(thread, "thread");
        ObjectUtil.checkNotNull(task, "task");

        if (!thread.isAlive()) {
            throw new IllegalArgumentException("thread must be alive.");
        }

        schedule(thread, task, true);
    }

    /**
     * Cancels the task scheduled via {@link #watch(Thread, Runnable)}.
     */
    public static void unwatch(Thread thread, Runnable task) {
        schedule(ObjectUtil.checkNotNull(thread, "thread"),
                ObjectUtil.checkNotNull(task, "task"),
                false);
    }

    private static void schedule(Thread thread, Runnable task, boolean isWatch) {
        pendingEntries.add(new Entry(thread, task, isWatch));

        if (started.compareAndSet(false, true)) {
            final Thread watcherThread = threadFactory.newThread(watcher);
            // Set to null to ensure we not create classloader leaks by holds a strong reference to the inherited
            // classloader.
            // See:
            // - https://github.com/netty/netty/issues/7290
            // - https://bugs.openjdk.java.net/browse/JDK-7008595
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                @Override
                public Void run() {
                    watcherThread.setContextClassLoader(null);
                    return null;
                }
            });

            watcherThread.start();
            ThreadDeathWatcher.watcherThread = watcherThread;
        }
    }

    /**
     * Waits until the thread of this watcher has no threads to watch and terminates itself.
     * Because a new watcher thread will be started again on {@link #watch(Thread, Runnable)},
     * this operation is only useful when you want to ensure that the watcher thread is terminated

Frequently Asked Questions

What is the ThreadDeathWatcher class?
ThreadDeathWatcher is a class in the netty codebase, defined in common/src/main/java/io/netty/util/ThreadDeathWatcher.java.
Where is ThreadDeathWatcher defined?
ThreadDeathWatcher is defined in common/src/main/java/io/netty/util/ThreadDeathWatcher.java at line 46.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free