/
githubmirror
/
guava
Обзор
Документация
Войти
/
githubmirror
/
guava
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
android/guava-tests/test/com/google/common/util/concurrent/StripedTest.java
221 строка
8 KB
cpovirk
Address some more counterfactual [CheckedExceptionNotThrown](https://errorprone.info/bugpattern/CheckedExceptionNotThrown) findings.
25 июн 2026, 20:33
25 июн 2026, 20:33
c37cd2a
Код
Авторство
О чём код?
/* * Copyright (C) 2011 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.util.concurrent; import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Sets.newHashSetWithExpectedSize; import static com.google.common.collect.Sets.newIdentityHashSet; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import com.google.common.annotations.GwtIncompatible; import com.google.common.annotations.J2ktIncompatible; import com.google.common.base.Functions; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.Ordering; import com.google.common.testing.GcFinalization; import com.google.common.testing.NullPointerTester; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import junit.framework.TestCase; import org.jspecify.annotations.NullUnmarked; /** * Tests for Striped. * * @author Dimitris Andreou */ @NullUnmarked @GwtIncompatible @J2ktIncompatible public class StripedTest extends TestCase { private static List<Striped<?>> strongImplementations() { return ImmutableList.of( Striped.readWriteLock(100), Striped.readWriteLock(256), Striped.lock(100), Striped.lock(256), Striped.custom(100, FAIR_LOCK_SUPPLER), Striped.custom(256, FAIR_LOCK_SUPPLER), Striped.semaphore(100, 1), Striped.semaphore(256, 1)); } private static final Supplier<Lock> FAIR_LOCK_SUPPLER = () -> new ReentrantLock(true); private static final Supplier<Semaphore> SEMAPHORE_SUPPLER = () -> new Semaphore(1, false); private static List<Striped<?>> weakImplementations() { return ImmutableList.<Striped<?>>builder() .add(new Striped.SmallLazyStriped<ReadWriteLock>(50, ReentrantReadWriteLock::new)) .add(new Striped.SmallLazyStriped<ReadWriteLock>(64, ReentrantReadWriteLock::new)) .add(new Striped.LargeLazyStriped<ReadWriteLock>(50, ReentrantReadWriteLock::new)) .add(new Striped.LargeLazyStriped<ReadWriteLock>(64, ReentrantReadWriteLock::new)) .add(new Striped.SmallLazyStriped<Lock>(50, ReentrantLock::new)) .add(new Striped.SmallLazyStriped<Lock>(64, ReentrantLock::new)) .add(new Striped.LargeLazyStriped<Lock>(50, ReentrantLock::new)) .add(new Striped.LargeLazyStriped<Lock>(64, ReentrantLock::new)) .add(new Striped.SmallLazyStriped<Semaphore>(50, SEMAPHORE_SUPPLER)) .add(new Striped.SmallLazyStriped<Semaphore>(64, SEMAPHORE_SUPPLER)) .add(new Striped.LargeLazyStriped<Semaphore>(50, SEMAPHORE_SUPPLER)) .add(new Striped.LargeLazyStriped<Semaphore>(64, SEMAPHORE_SUPPLER)) .add(Striped.lazyWeakCustom(50, FAIR_LOCK_SUPPLER)) .add(Striped.lazyWeakCustom(64, FAIR_LOCK_SUPPLER)) .build(); } private static Iterable<Striped<?>> allImplementations() { return concat(strongImplementations(), weakImplementations()); } public void testNull() { for (Striped<?> striped : allImplementations()) { new NullPointerTester().testAllPublicInstanceMethods(striped); } } public void testSizes() { // not bothering testing all variations, since we know they share implementations assertThat(Striped.lock(100).size()).isAtLeast(100); assertTrue(Striped.lock(256).size() == 256); assertThat(Striped.lazyWeakLock(100).size()).isAtLeast(100); assertTrue(Striped.lazyWeakLock(256).size() == 256); } public void testWeakImplementations() { for (Striped<?> striped : weakImplementations()) { WeakReference<Object> weakRef = getWeakReferenceToStripe(striped); GcFinalization.awaitClear(weakRef); } } private WeakReference<Object> getWeakReferenceToStripe(Striped<?> striped) { return new WeakReference<>(striped.get(new Object())); } public void testWeakReadWrite() { Striped<ReadWriteLock> striped = Striped.lazyWeakReadWriteLock(1000); Object key = new Object(); Lock readLock = striped.get(key).readLock(); WeakReference<Object> garbage = createGarbage(); GcFinalization.awaitClear(garbage); Lock writeLock = striped.get(key).writeLock(); readLock.lock(); try { assertFalse(writeLock.tryLock()); } finally { readLock.unlock(); } } private WeakReference<Object> createGarbage() { return new WeakReference<>(new Object()); } public void testStrongImplementations() { for (Striped<?> striped : strongImplementations()) { WeakReference<Object> weakRef = getWeakReferenceToStripe(striped); WeakReference<Object> garbage = createGarbage(); GcFinalization.awaitClear(garbage); assertThat(weakRef.get()).isNotNull(); } } public void testMaximalWeakStripedLock() { Striped<Lock> stripedLock = Striped.lazyWeakLock(Integer.MAX_VALUE); for (int i = 0; i < 10000; i++) { stripedLock.get(new Object()).lock(); // nothing special (e.g. an exception) happens } } public void testBulkGetReturnsSorted() { for (Striped<?> striped : allImplementations()) { Map<Object, Integer> indexByLock = new HashMap<>(); for (int i = 0; i < striped.size(); i++) { indexByLock.put(striped.getAt(i), i); } // ensure that bulkGet returns locks in monotonically increasing order for (int objectsNum = 1; objectsNum <= striped.size() * 2; objectsNum++) { Set<Object> objects = newHashSetWithExpectedSize(objectsNum); for (int i = 0; i < objectsNum; i++) { objects.add(new Object()); } Iterable<?> locks = striped.bulkGet(objects); assertTrue(Ordering.natural().onResultOf(Functions.forMap(indexByLock)).isOrdered(locks)); // check idempotency Iterable<?> locks2 = striped.bulkGet(objects); assertEquals(newArrayList(locks), newArrayList(locks2)); } } } /** Checks idempotency, and that we observe the promised number of stripes. */ public void testBasicInvariants() { for (Striped<?> striped : allImplementations()) { assertBasicInvariants(striped); } } private static void assertBasicInvariants(Striped<?> striped) { Set<Object> observed = newIdentityHashSet(); // for the sake of weakly referenced locks. // this gets the stripes with #getAt(index) for (int i = 0; i < striped.size(); i++) { Object object = striped.getAt(i); assertThat(object).isNotNull(); assertThat(striped.getAt(i)).isSameInstanceAs(object); // idempotent observed.add(object); } assertTrue("All stripes observed", observed.size() == striped.size()); // this uses #get(key), makes sure an already observed stripe is returned for (int i = 0; i < striped.size() * 100; i++) { assertTrue(observed.contains(striped.get(new Object()))); } assertThrows(IndexOutOfBoundsException.class, () -> striped.getAt(-1)); int size = striped.size(); assertThrows(IndexOutOfBoundsException.class, () -> striped.getAt(size)); } public void testMaxSize() { for (Striped<?> striped : ImmutableList.of( Striped.lazyWeakLock(Integer.MAX_VALUE), Striped.lazyWeakSemaphore(Integer.MAX_VALUE, Integer.MAX_VALUE), Striped.lazyWeakReadWriteLock(Integer.MAX_VALUE))) { for (int i = 0; i < 3; i++) { // doesn't throw exception Object unused = striped.getAt(Integer.MAX_VALUE - i); } } } }