@@ -223,7 +223,7 @@ private static final class Link extends AtomicInteger {
223223 private WeakOrderQueue next ;
224224 private final WeakReference <Thread > owner ;
225225 private final int id = ID_GENERATOR .getAndIncrement ();
226- private final Stack <?> stack ;
226+ private final AtomicInteger availableSharedCapacity ;
227227
228228 WeakOrderQueue (Stack <?> stack , Thread thread ) {
229229 head = tail = new Link ();
@@ -232,19 +232,42 @@ private static final class Link extends AtomicInteger {
232232 next = stack .head ;
233233 stack .head = this ;
234234 }
235- this .stack = stack ;
235+
236+ // Its important that we not store the Stack itself in the WeakOrderQueue as the Stack also is used in
237+ // the WeakHashMap as key. So just store the enclosed AtomicInteger which should allow to have the
238+ // Stack itself GCed.
239+ availableSharedCapacity = stack .availableSharedCapacity ;
240+
236241 // We allocated a Link so reserve the space
237- boolean reserved = stack . reserveSpace (LINK_CAPACITY );
242+ boolean reserved = reserveSpace (LINK_CAPACITY );
238243 assert reserved ;
239244 }
240245
246+ private boolean reserveSpace (int space ) {
247+ assert space >= 0 ;
248+ for (;;) {
249+ int available = availableSharedCapacity .get ();
250+ if (available < space ) {
251+ return false ;
252+ }
253+ if (availableSharedCapacity .compareAndSet (available , available - space )) {
254+ return true ;
255+ }
256+ }
257+ }
258+
259+ private void reclaimSpace (int space ) {
260+ assert space >= 0 ;
261+ availableSharedCapacity .addAndGet (space );
262+ }
263+
241264 void add (DefaultHandle <?> handle ) {
242265 handle .lastRecycledId = id ;
243266
244267 Link tail = this .tail ;
245268 int writeIndex ;
246269 if ((writeIndex = tail .get ()) == LINK_CAPACITY ) {
247- if (!stack . reserveSpace (LINK_CAPACITY )) {
270+ if (!reserveSpace (LINK_CAPACITY )) {
248271 // Drop it.
249272 return ;
250273 }
@@ -314,7 +337,7 @@ boolean transfer(Stack<?> dst) {
314337
315338 if (srcEnd == LINK_CAPACITY && head .next != null ) {
316339 // Add capacity back as the Link is GCed.
317- stack . reclaimSpace (LINK_CAPACITY );
340+ reclaimSpace (LINK_CAPACITY );
318341
319342 this .head = head .next ;
320343 }
@@ -339,7 +362,7 @@ static final class Stack<T> {
339362 private DefaultHandle <?>[] elements ;
340363 private final int maxCapacity ;
341364 private int size ;
342- private final AtomicInteger availableSharedCapacity ;
365+ final AtomicInteger availableSharedCapacity ;
343366
344367 private volatile WeakOrderQueue head ;
345368 private WeakOrderQueue cursor , prev ;
@@ -352,24 +375,6 @@ static final class Stack<T> {
352375 elements = new DefaultHandle [min (INITIAL_CAPACITY , maxCapacity )];
353376 }
354377
355- boolean reserveSpace (int space ) {
356- assert space >= 0 ;
357- for (;;) {
358- int available = availableSharedCapacity .get ();
359- if (available < space ) {
360- return false ;
361- }
362- if (availableSharedCapacity .compareAndSet (available , available - space )) {
363- return true ;
364- }
365- }
366- }
367-
368- void reclaimSpace (int space ) {
369- assert space >= 0 ;
370- availableSharedCapacity .addAndGet (space );
371- }
372-
373378 int increaseCapacity (int expectedCapacity ) {
374379 int newCapacity = elements .length ;
375380 int maxCapacity = this .maxCapacity ;
0 commit comments