88final class ThreadLocalContextManager implements ContextManager {
99 static final ThreadLocalContextManager INSTANCE = new ThreadLocalContextManager ();
1010
11- private static final ThreadLocal <Context []> CURRENT_HOLDER =
12- ThreadLocal .withInitial (() -> new Context [] { Context . root ()} );
11+ private static final ThreadLocal <ContextHolder > CONTEXT_HOLDER =
12+ ThreadLocal .withInitial (ContextHolder :: new );
1313
1414 private final Object listenersWriteLock = new Object ();
15- private volatile ContextListener [] listeners = {};
15+ volatile ContextListener [] listeners = {};
1616
1717 @ Override
1818 public Context current () {
19- return CURRENT_HOLDER .get ()[ 0 ] ;
19+ return CONTEXT_HOLDER .get (). current ;
2020 }
2121
2222 @ Override
@@ -25,9 +25,9 @@ public ContextScope attach(Context context) {
2525 }
2626
2727 ContextScope doAttach (Context context , @ Nullable ContextContinuationImpl continuation ) {
28- Context [] holder = CURRENT_HOLDER .get ();
28+ ContextHolder holder = CONTEXT_HOLDER .get ();
2929
30- Context previous = holder [ 0 ] ;
30+ Context previous = holder . current ;
3131 if (context == previous ) {
3232 if (continuation != null ) {
3333 // already attached, safe to release early to avoid resource leak
@@ -38,7 +38,7 @@ ContextScope doAttach(Context context, @Nullable ContextContinuationImpl continu
3838
3939 ContextListener [] ls = listeners ;
4040 notifyDetach (previous , ls );
41- holder [ 0 ] = context ;
41+ holder . current = context ;
4242 notifyAttach (context , ls );
4343
4444 if (continuation == null ) {
@@ -50,16 +50,16 @@ ContextScope doAttach(Context context, @Nullable ContextContinuationImpl continu
5050
5151 @ Override
5252 public Context swap (Context context ) {
53- Context [] holder = CURRENT_HOLDER .get ();
53+ ContextHolder holder = CONTEXT_HOLDER .get ();
5454
55- Context previous = holder [ 0 ] ;
55+ Context previous = holder . current ;
5656 if (context == previous ) {
5757 return previous ;
5858 }
5959
6060 ContextListener [] ls = listeners ;
6161 notifyDetach (previous , ls );
62- holder [ 0 ] = context ;
62+ holder . current = context ;
6363 notifyAttach (context , ls );
6464
6565 return previous ;
@@ -142,12 +142,12 @@ static void notifyRelease(Context context, ContextListener[] listeners) {
142142 private static class ContextScopeImpl implements ContextScope {
143143
144144 private final Context context ;
145- private final Context [] holder ;
145+ private final ContextHolder holder ;
146146 private final Context previous ;
147147
148148 private boolean closed ;
149149
150- ContextScopeImpl (Context context , Context [] holder , Context previous ) {
150+ ContextScopeImpl (Context context , ContextHolder holder , Context previous ) {
151151 this .context = context ;
152152 this .holder = holder ;
153153 this .previous = previous ;
@@ -162,10 +162,10 @@ public final Context context() {
162162 public void close () {
163163 if (!closed ) {
164164 // check for out-of-order close to avoid corrupting the current state
165- if (context == holder [ 0 ] ) {
165+ if (context == holder . current ) {
166166 ContextListener [] ls = INSTANCE .listeners ;
167167 notifyDetach (context , ls );
168- holder [ 0 ] = previous ;
168+ holder . current = previous ;
169169 notifyAttach (previous , ls );
170170 closed = true ;
171171 }
@@ -178,7 +178,7 @@ private static final class ResumedScopeImpl extends ContextScopeImpl {
178178
179179 ResumedScopeImpl (
180180 Context context ,
181- Context [] holder ,
181+ ContextHolder holder ,
182182 Context previous ,
183183 @ Nullable ContextContinuationImpl continuation ) {
184184 super (context , holder , previous );
@@ -285,4 +285,8 @@ void releaseOnScopeClose() {
285285 } /* else there are outstanding resumes or hold is in place */
286286 }
287287 }
288+
289+ private static final class ContextHolder {
290+ Context current = Context .root ();
291+ }
288292}
0 commit comments