(int index)
| 389 | } |
| 390 | |
| 391 | @Override |
| 392 | public L getAt(int index) { |
| 393 | if (size != Integer.MAX_VALUE) { |
| 394 | Preconditions.checkElementIndex(index, size()); |
| 395 | } // else no check necessary, all index values are valid |
| 396 | ArrayReference<? extends L> existingRef = locks.get(index); |
| 397 | L existing = existingRef == null ? null : existingRef.get(); |
| 398 | if (existing != null) { |
| 399 | return existing; |
| 400 | } |
| 401 | L created = supplier.get(); |
| 402 | ArrayReference<L> newRef = new ArrayReference<L>(created, index, queue); |
| 403 | while (!locks.compareAndSet(index, existingRef, newRef)) { |
| 404 | // we raced, we need to re-read and try again |
| 405 | existingRef = locks.get(index); |
| 406 | existing = existingRef == null ? null : existingRef.get(); |
| 407 | if (existing != null) { |
| 408 | return existing; |
| 409 | } |
| 410 | } |
| 411 | drainQueue(); |
| 412 | return created; |
| 413 | } |
| 414 | |
| 415 | // N.B. Draining the queue is only necessary to ensure that we don't accumulate empty references |
| 416 | // in the array. We could skip this if we decide we don't care about holding on to Reference |
nothing calls this directly
no test coverage detected