@Test
    @Timeout(15)
    // If the test times out, then there's a deadlock in the test but not necessarily the code
    public void testSimultaneousUpwardAndDownwardDelegating() throws Exception {
        String t1Class = TestPlugins.TestPlugin.SAMPLING_CONVERTER.className();
        // Grab a reference to the target PluginClassLoader before activating breakpoints
        ClassLoader connectorLoader = plugins.connectorLoader(t1Class);

        // THREAD 1: loads a class by delegating downward starting from the DelegatingClassLoader
        // DelegatingClassLoader breakpoint will only trigger on this thread
        dclBreakpoint.set(t1Class::equals);
        Runnable thread1 = () -> {
            // Use the DelegatingClassLoader as the current context loader
            try (LoaderSwap loaderSwap = plugins.withClassLoader(plugins.delegatingLoader())) {

                // Load an isolated plugin from the delegating classloader, which will
                // 1. Enter the DelegatingClassLoader
                // 2. Wait on dclBreakpoint for test to continue
                // 3. Enter the PluginClassLoader
                // 4. Load the isolated plugin class and return
                new AbstractConfig(
                        new ConfigDef().define("a.class", Type.CLASS, Importance.HIGH, ""),
                        Collections.singletonMap("a.class", t1Class));
            }
        };

        // THREAD 2: loads a class by delegating upward starting from the PluginClassLoader
        // Use any non-plugin class that no plugins depend on, so that the class isn't loaded during plugin discovery
        String t2Class = Mockito.class.getName();
        // PluginClassLoader breakpoint will only trigger on this thread
        pclBreakpoint.set(t2Class::equals);
        Runnable thread2 = () -> {
            // Use the PluginClassLoader as the current context loader
            try (LoaderSwap loaderSwap = plugins.withClassLoader(connectorLoader)) {
                // Load a non-isolated class from the plugin classloader, which will
                // 1. Enter the PluginClassLoader
                // 2. Wait for the test to continue
                // 3. Enter the DelegatingClassLoader
                // 4. Load the non-isolated class and return
                new AbstractConfig(new ConfigDef().define("a.class", Type.CLASS, Importance.HIGH, ""),
                        Collections.singletonMap("a.class", t2Class));
            }
        };

        // STEP 1: Have T1 enter the DelegatingClassLoader and pause
        exec.submit(thread1);
        // T1 enters ConfigDef::parseType
        // T1 enters DelegatingClassLoader::loadClass
        dclBreakpoint.testAwait();
        dclBreakpoint.testAwait();
        // T1 exits DelegatingClassLoader::loadClass
        // T1 enters Class::forName
        // T1 enters DelegatingClassLoader::loadClass
        dclBreakpoint.testAwait();
        // T1 waits in the delegating classloader while we set up the other thread
        dumpThreads("step 1, T1 waiting in DelegatingClassLoader");

        // STEP 2: Have T2 enter PluginClassLoader, delegate upward to the Delegating classloader
        exec.submit(thread2);
        // T2 enters PluginClassLoader::loadClass
        pclBreakpoint.testAwait();
        // T2 falls through to ClassLoader::loadClass
        pclBreakpoint.testAwait();
        // T2 delegates upwards to DelegatingClassLoader::loadClass
        // T2 enters ClassLoader::loadClass and loads the class from the parent (CLASSPATH)
        dumpThreads("step 2, T2 entered DelegatingClassLoader and is loading class from parent");

        // STEP 3: Resume T1 and have it enter the PluginClassLoader
        dclBreakpoint.testAwait();
        // T1 enters PluginClassLoader::loadClass
        dumpThreads("step 3, T1 entered PluginClassLoader and is/was loading class from isolated jar");

        // If the DelegatingClassLoader and PluginClassLoader are both not parallel capable, then this test will deadlock
        // Otherwise, T1 should be able to complete it's load from the PluginClassLoader concurrently with T2,
        // before releasing the DelegatingClassLoader and allowing T2 to complete.
        // As the DelegatingClassLoader is not parallel capable, it must be the case that PluginClassLoader is.
        assertNoDeadlocks();
    }
From the test orchestrating thread, await for the test thread to continue execution
@throws InterruptedException If the current thread is interrupted while waiting
@throws BrokenBarrierException If the test thread is interrupted while waiting
@throws TimeoutException If the barrier is not reached before 1s passes.
connect/runtime/src/test/java/org/apache/kafka/connect/runtime/isolation/SynchronizationTest.java