2929 * loop would create > 1000 stack frames and cause {@code StackOverflowError}.</p>
3030 *
3131 * <p>The trampoline intercepts this recursion: instead of executing the next iteration
32- * immediately (which would deepen the stack), it enqueues the work and returns, allowing
33- * the stack to unwind. A flat loop at the top then processes enqueued work iteratively,
32+ * immediately (which would deepen the stack), it enqueues the continuation and returns, allowing
33+ * the stack to unwind. A flat loop at the top then processes enqueued continuation iteratively,
3434 * maintaining constant stack depth regardless of iteration count.</p>
3535 *
3636 * <p>Since async chains are sequential, at most one task is pending at any time.
3737 * The trampoline uses a single slot rather than a queue.</p>
3838 *
3939 * The first call on a thread becomes the "trampoline owner" and runs the drain loop.
40- * Subsequent (re-entrant) calls on the same thread enqueue their work and return immediately.</p>
40+ * Subsequent (re-entrant) calls on the same thread enqueue their continuation and return immediately.</p>
4141 *
4242 * <p>This class is not part of the public API and may be removed or changed at any time</p>
4343 */
4444@ NotThreadSafe
4545public final class AsyncTrampoline {
4646
47- private static final ThreadLocal <Bounce > TRAMPOLINE = new ThreadLocal <>();
47+ private static final ThreadLocal <ContinuationHolder > TRAMPOLINE = new ThreadLocal <>();
4848
4949 private AsyncTrampoline () {}
5050
5151 /**
52- * Execute work through the trampoline. If no trampoline is active, become the owner
53- * and drain all enqueued work . If a trampoline is already active, enqueue and return.
52+ * Execute continuation through the trampoline. If no trampoline is active, become the owner
53+ * and drain all enqueued continuations . If a trampoline is already active, enqueue and return.
5454 */
55- public static void run (final Runnable work ) {
56- Bounce bounce = TRAMPOLINE .get ();
57- if (bounce != null ) {
58- bounce .enqueue (work );
55+ public static void run (final Runnable continuation ) {
56+ ContinuationHolder continuationHolder = TRAMPOLINE .get ();
57+ if (continuationHolder != null ) {
58+ continuationHolder .enqueue (continuation );
5959 } else {
60- bounce = new Bounce ();
61- TRAMPOLINE .set (bounce );
60+ continuationHolder = new ContinuationHolder ();
61+ TRAMPOLINE .set (continuationHolder );
6262 try {
63- work .run ();
64- while (bounce . work != null ) {
65- Runnable workToRun = bounce . work ;
66- bounce . work = null ;
67- workToRun .run ();
63+ continuation .run ();
64+ while (continuationHolder . continuation != null ) {
65+ Runnable continuationToRun = continuationHolder . continuation ;
66+ continuationHolder . continuation = null ;
67+ continuationToRun .run ();
6868 }
6969 } finally {
7070 TRAMPOLINE .remove ();
@@ -73,19 +73,19 @@ public static void run(final Runnable work) {
7373 }
7474
7575 /**
76- * A single-slot container for deferred work .
77- * At most one task is pending at any time in a sequential async chain.
76+ * A single-slot container for continuation .
77+ * At most one continuation is pending at any time in a sequential async chain.
7878 */
7979 @ NotThreadSafe
80- private static final class Bounce {
80+ private static final class ContinuationHolder {
8181 @ Nullable
82- private Runnable work ;
82+ private Runnable continuation ;
8383
84- void enqueue (final Runnable task ) {
85- if (this .work != null ) {
84+ void enqueue (final Runnable continuation ) {
85+ if (this .continuation != null ) {
8686 throw new AssertionError ("Trampoline slot already occupied" );
8787 }
88- this .work = task ;
88+ this .continuation = continuation ;
8989 }
9090 }
9191}
0 commit comments