java.util.concurrent.atomic.AtomicReferenceArray#set()源码实例Demo

下面列出了java.util.concurrent.atomic.AtomicReferenceArray#set() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: j2objc   文件: AtomicReferenceArrayTest.java
/**
 * repeated weakCompareAndSet succeeds in changing value when equal
 * to expected
 */
public void testWeakCompareAndSet() {
    AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
    for (int i = 0; i < SIZE; i++) {
        aa.set(i, one);
        do {} while (!aa.weakCompareAndSet(i, one, two));
        do {} while (!aa.weakCompareAndSet(i, two, m4));
        assertSame(m4, aa.get(i));
        do {} while (!aa.weakCompareAndSet(i, m4, seven));
        assertSame(seven, aa.get(i));
    }
}
 
源代码2 项目: openjdk-jdk9   文件: AtomicReferenceArrayTest.java
/**
 * a deserialized serialized array holds same values
 */
public void testSerialization() throws Exception {
    AtomicReferenceArray x = new AtomicReferenceArray(SIZE);
    for (int i = 0; i < SIZE; i++) {
        x.set(i, new Integer(-i));
    }
    AtomicReferenceArray y = serialClone(x);
    assertNotSame(x, y);
    assertEquals(x.length(), y.length());
    for (int i = 0; i < SIZE; i++) {
        assertEquals(x.get(i), y.get(i));
    }
}
 
源代码3 项目: codebuff   文件: LocalCache.java
void clear() {
  if (count != 0) { // read-volatile
    lock();
    try {
      long now = map.ticker.read();
      preWriteCleanup(now);
      AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
      for (int i = 0; i < table.length(); ++i) {
        for (ReferenceEntry<K, V> e = table.get(i); e != null; e = e.getNext()) {
          // Loading references aren't actually in the map yet.
          if (e.getValueReference().isActive()) {
            K key = e.getKey();
            V value = e.getValueReference().get();
            RemovalCause cause = (key == null || value == null) ? RemovalCause.COLLECTED : RemovalCause.EXPLICIT;
            enqueueNotification(key, e.getHash(), value, e.getValueReference().getWeight(), cause);
          }
        }
      }
      for (int i = 0; i < table.length(); ++i) {
        table.set(i, null);
      }
      clearReferenceQueues();
      writeQueue.clear();
      accessQueue.clear();
      readCount.set(0);
      ++modCount;
      count = 0; // write-volatile
    } finally {
      unlock();
      postWriteCleanup();
    }
  }
}
 
源代码4 项目: openjdk-jdk9   文件: AtomicReferenceArray9Test.java
/**
 * compareAndExchange succeeds in changing value if equal to
 * expected else fails
 */
public void testCompareAndExchange() {
    AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<>(SIZE);
    for (int i = 0; i < SIZE; i++) {
        aa.set(i, one);
        assertEquals(one, aa.compareAndExchange(i, one, two));
        assertEquals(two, aa.compareAndExchange(i, two, m4));
        assertEquals(m4, aa.get(i));
        assertEquals(m4, aa.compareAndExchange(i,m5, seven));
        assertEquals(m4, aa.get(i));
        assertEquals(m4, aa.compareAndExchange(i, m4, seven));
        assertEquals(seven, aa.get(i));
    }
}
 
源代码5 项目: j2objc   文件: AtomicReferenceArrayTest.java
/**
 * getAndSet returns previous value and sets to given value at given index
 */
public void testGetAndSet() {
    AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
    for (int i = 0; i < SIZE; i++) {
        aa.set(i, one);
        assertSame(one, aa.getAndSet(i, zero));
        assertSame(zero, aa.getAndSet(i, m10));
        assertSame(m10, aa.getAndSet(i, one));
    }
}
 
源代码6 项目: codebuff   文件: MapMakerInternalMap.java
/**
 * Removes an entry whose value has been garbage collected.
 */

@CanIgnoreReturnValue
boolean reclaimValue(K key, int hash, ValueReference<K, V> valueReference) {
  lock();
  try {
    int newCount = this.count - 1;
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);
    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> v = e.getValueReference();
        if (v == valueReference) {
          ++modCount;
          ReferenceEntry<K, V> newFirst = removeFromChain(first, e);
          newCount = this.count - 1;
          table.set(index, newFirst);
          this.count = newCount; // write-volatile
          return true;
        }
        return false;
      }
    }
    return false;
  } finally {
    unlock();
  }
}
 
源代码7 项目: codebuff   文件: MapMakerInternalMap.java
/**
 * Removes an entry whose value has been garbage collected.
 */
@CanIgnoreReturnValue
boolean reclaimValue(K key, int hash, ValueReference<K, V> valueReference) {
  lock();
  try {
    int newCount = this.count - 1;
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);

    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash
          && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> v = e.getValueReference();
        if (v == valueReference) {
          ++modCount;
          ReferenceEntry<K, V> newFirst = removeFromChain(first, e);
          newCount = this.count - 1;
          table.set(index, newFirst);
          this.count = newCount; // write-volatile
          return true;
        }
        return false;
      }
    }

    return false;
  } finally {
    unlock();
  }
}
 
源代码8 项目: openjdk-jdk9   文件: AtomicReferenceArrayTest.java
/**
 * repeated weakCompareAndSet succeeds in changing value when equal
 * to expected
 */
public void testWeakCompareAndSet() {
    AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
    for (int i = 0; i < SIZE; i++) {
        aa.set(i, one);
        do {} while (!aa.weakCompareAndSet(i, one, two));
        do {} while (!aa.weakCompareAndSet(i, two, m4));
        assertSame(m4, aa.get(i));
        do {} while (!aa.weakCompareAndSet(i, m4, seven));
        assertSame(seven, aa.get(i));
    }
}
 
源代码9 项目: codebuff   文件: MapMakerInternalMap.java
boolean remove(Object key, int hash, Object value) {
  lock();
  try {
    preWriteCleanup();
    int newCount = this.count - 1;
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);
    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        boolean explicitRemoval = false;
        if (map.valueEquivalence.equivalent(value, entryValue)) {
          explicitRemoval = true;
        } else if (isCollected(valueReference)) {
          // TODO(kak): Remove this branch
        } else {
          return false;
        }

        ++modCount;
        ReferenceEntry<K, V> newFirst = removeFromChain(first, e);
        newCount = this.count - 1;
        table.set(index, newFirst);
        this.count = newCount; // write-volatile
        return explicitRemoval;
      }
    }
    return false;
  } finally {
    unlock();
  }
}
 
源代码10 项目: openjdk-jdk9   文件: AtomicReferenceArrayTest.java
/**
 * getAndSet returns previous value and sets to given value at given index
 */
public void testGetAndSet() {
    AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
    for (int i = 0; i < SIZE; i++) {
        aa.set(i, one);
        assertSame(one, aa.getAndSet(i, zero));
        assertSame(zero, aa.getAndSet(i, m10));
        assertSame(m10, aa.getAndSet(i, one));
    }
}
 
源代码11 项目: consulo   文件: ResolveCache.java
private static void clearArray(AtomicReferenceArray<?> array) {
  for (int i = 0; i < array.length(); i++) {
    array.set(i, null);
  }
}
 
源代码12 项目: codebuff   文件: LocalCache.java
V lockedGetOrLoad(K key, int hash, CacheLoader<? super K, V> loader) throws ExecutionException {
  ReferenceEntry<K, V> e;
  ValueReference<K, V> valueReference = null;
  LoadingValueReference<K, V> loadingValueReference = null;
  boolean createNewEntry = true;
  lock();
  try {
    // re-read ticker once inside the lock
    long now = map.ticker.read();
    preWriteCleanup(now);
    int newCount = this.count - 1;
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);
    for (e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        valueReference = e.getValueReference();
        if (valueReference.isLoading()) {
          createNewEntry = false;
        } else {
          V value = valueReference.get();
          if (value == null) {
            enqueueNotification(entryKey, hash, value, valueReference.getWeight(), RemovalCause.COLLECTED);
          } else if (map.isExpired(e, now)) {
            // This is a duplicate check, as preWriteCleanup already purged expired
            // entries, but let's accomodate an incorrect expiration queue.
            enqueueNotification(entryKey, hash, value, valueReference.getWeight(), RemovalCause.EXPIRED);
          } else {
            recordLockedRead(e, now);
            statsCounter.recordHits(1);
            // we were concurrent with loading; don't consider refresh
            return value;
          }

          // immediately reuse invalid entries
          writeQueue.remove(e);
          accessQueue.remove(e);
          this.count = newCount; // write-volatile
        }
        break;
      }
    }
    if (createNewEntry) {
      loadingValueReference = new LoadingValueReference<K, V>();
      if (e == null) {
        e = newEntry(key, hash, first);
        e.setValueReference(loadingValueReference);
        table.set(index, e);
      } else {
        e.setValueReference(loadingValueReference);
      }
    }
  } finally {
    unlock();
    postWriteCleanup();
  }
  if (createNewEntry) {
    try {
      // Synchronizes on the entry to allow failing fast when a recursive load is
      // detected. This may be circumvented when an entry is copied, but will fail fast most
      // of the time.
      synchronized (e) {
        return loadSync(key, hash, loadingValueReference, loader);
      }
    } finally {
      statsCounter.recordMisses(1);
    }
  } else {
    // The entry already exists. Wait for loading.
    return waitForLoadingValue(e, key, valueReference);
  }
}
 
源代码13 项目: bazel-buildfarm   文件: LocalCache.java
boolean storeLoadedValue(
    K key, int hash, LoadingValueReference<K, V> oldValueReference, V newValue) {
  lock();
  try {
    long now = map.ticker.read();
    preWriteCleanup(now);

    int newCount = this.count + 1;
    if (newCount > this.threshold) { // ensure capacity
      expand();
      newCount = this.count + 1;
    }

    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);

    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash
          && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        // replace the old LoadingValueReference if it's live, otherwise
        // perform a putIfAbsent
        if (oldValueReference == valueReference
            || (entryValue == null && valueReference != UNSET)) {
          ++modCount;
          if (oldValueReference.isActive()) {
            RemovalCause cause =
                (entryValue == null) ? RemovalCause.COLLECTED : RemovalCause.REPLACED;
            enqueueNotification(key, hash, entryValue, oldValueReference.getWeight(), cause);
            newCount--;
          }
          setValue(e, key, newValue, now);
          this.count = newCount; // write-volatile
          evictEntries(e);
          return true;
        }

        // the loaded value was already clobbered
        enqueueNotification(key, hash, newValue, 0, RemovalCause.REPLACED);
        return false;
      }
    }

    ++modCount;
    ReferenceEntry<K, V> newEntry = newEntry(key, hash, first);
    setValue(newEntry, key, newValue, now);
    table.set(index, newEntry);
    this.count = newCount; // write-volatile
    evictEntries(newEntry);
    return true;
  } finally {
    unlock();
    postWriteCleanup();
  }
}
 
源代码14 项目: bazel-buildfarm   文件: LocalCache.java
boolean replace(K key, int hash, V oldValue, V newValue) {
  lock();
  try {
    long now = map.ticker.read();
    preWriteCleanup(now);

    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);

    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash
          && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        if (entryValue == null) {
          if (valueReference.isActive()) {
            // If the value disappeared, this entry is partially collected.
            int newCount = this.count - 1;
            ++modCount;
            ReferenceEntry<K, V> newFirst =
                removeValueFromChain(
                    first,
                    e,
                    entryKey,
                    hash,
                    entryValue,
                    valueReference,
                    RemovalCause.COLLECTED);
            newCount = this.count - 1;
            table.set(index, newFirst);
            this.count = newCount; // write-volatile
          }
          return false;
        }

        if (map.valueEquivalence.equivalent(oldValue, entryValue)) {
          ++modCount;
          enqueueNotification(
              key, hash, entryValue, valueReference.getWeight(), RemovalCause.REPLACED);
          setValue(e, key, newValue, now);
          evictEntries(e);
          return true;
        } else {
          // Mimic
          // "if (map.containsKey(key) && map.get(key).equals(oldValue))..."
          recordLockedRead(e, now);
          return false;
        }
      }
    }

    return false;
  } finally {
    unlock();
    postWriteCleanup();
  }
}
 
源代码15 项目: codebuff   文件: LocalCache.java
boolean replace(K key, int hash, V oldValue, V newValue) {
  lock();
  try {
    long now = map.ticker.read();
    preWriteCleanup(now);
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);
    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        if (entryValue == null) {
          if (valueReference.isActive()) {
            // If the value disappeared, this entry is partially collected.
            int newCount = this.count - 1;
            ++modCount;
            ReferenceEntry<K, V> newFirst = removeValueFromChain(first, e, entryKey, hash, entryValue, valueReference, RemovalCause.COLLECTED);
            newCount = this.count - 1;
            table.set(index, newFirst);
            this.count = newCount; // write-volatile
          }
          return false;
        }
        if (map.valueEquivalence.equivalent(oldValue, entryValue)) {
          ++modCount;
          enqueueNotification(key, hash, entryValue, valueReference.getWeight(), RemovalCause.REPLACED);
          setValue(e, key, newValue, now);
          evictEntries(e);
          return true;
        } else {
          // Mimic
          // "if (map.containsKey(key) && map.get(key).equals(oldValue))..."
          recordLockedRead(e, now);
          return false;
        }
      }
    }
    return false;
  } finally {
    unlock();
    postWriteCleanup();
  }
}
 
源代码16 项目: codebuff   文件: LocalCache.java
boolean replace(K key, int hash, V oldValue, V newValue) {
  lock();
  try {
    long now = map.ticker.read();
    preWriteCleanup(now);
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);
    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        if (entryValue == null) {
          if (valueReference.isActive()) {
            // If the value disappeared, this entry is partially collected.
            int newCount = this.count - 1;
            ++modCount;
            ReferenceEntry<K, V> newFirst = removeValueFromChain(first, e, entryKey, hash, entryValue, valueReference, RemovalCause.COLLECTED);
            newCount = this.count - 1;
            table.set(index, newFirst);
            this.count = newCount; // write-volatile
          }
          return false;
        }
        if (map.valueEquivalence.equivalent(oldValue, entryValue)) {
          ++modCount;
          enqueueNotification(key, hash, entryValue, valueReference.getWeight(), RemovalCause.REPLACED);
          setValue(e, key, newValue, now);
          evictEntries(e);
          return true;
        } else {
          // Mimic
          // "if (map.containsKey(key) && map.get(key).equals(oldValue))..."
          recordLockedRead(e, now);
          return false;
        }
      }
    }
    return false;
  } finally {
    unlock();
    postWriteCleanup();
  }
}
 
源代码17 项目: codebuff   文件: LocalCache.java
boolean storeLoadedValue(K key, int hash, LoadingValueReference<K, V> oldValueReference, V newValue) {
  lock();
  try {
    long now = map.ticker.read();
    preWriteCleanup(now);
    int newCount = this.count + 1;
    if (newCount > this.threshold) { // ensure capacity
      expand();
      newCount = this.count + 1;
    }
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);
    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        // replace the old LoadingValueReference if it's live, otherwise
        // perform a putIfAbsent
        if (oldValueReference == valueReference
            || (entryValue == null && valueReference != UNSET)) {
          ++modCount;
          if (oldValueReference.isActive()) {
            RemovalCause cause = (entryValue == null) ? RemovalCause.COLLECTED : RemovalCause.REPLACED;
            enqueueNotification(key, hash, entryValue, oldValueReference.getWeight(), cause);
            newCount--;
          }
          setValue(e, key, newValue, now);
          this.count = newCount; // write-volatile
          evictEntries(e);
          return true;
        }

        // the loaded value was already clobbered
        enqueueNotification(key, hash, newValue, 0, RemovalCause.REPLACED);
        return false;
      }
    }

    ++modCount;
    ReferenceEntry<K, V> newEntry = newEntry(key, hash, first);
    setValue(newEntry, key, newValue, now);
    table.set(index, newEntry);
    this.count = newCount; // write-volatile
    evictEntries(newEntry);
    return true;
  } finally {
    unlock();
    postWriteCleanup();
  }
}
 
源代码18 项目: codebuff   文件: LocalCache.java
@Nullable
V put(K key, int hash, V value, boolean onlyIfAbsent) {
  lock();
  try {
    long now = map.ticker.read();
    preWriteCleanup(now);
    int newCount = this.count + 1;
    if (newCount > this.threshold) { // ensure capacity
      expand();
      newCount = this.count + 1;
    }
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);

    // Look for an existing entry.
    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        // We found an existing entry.
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        if (entryValue == null) {
          ++modCount;
          if (valueReference.isActive()) {
            enqueueNotification(key, hash, entryValue, valueReference.getWeight(), RemovalCause.COLLECTED);
            setValue(e, key, value, now);
            newCount = this.count; // count remains unchanged
          } else {
            setValue(e, key, value, now);
            newCount = this.count + 1;
          }
          this.count = newCount; // write-volatile
          evictEntries(e);
          return null;
        }
        else if (onlyIfAbsent) {
          // Mimic
          // "if (!map.containsKey(key)) ...
          // else return map.get(key);
          recordLockedRead(e, now);
          return entryValue;
        } else {
          // clobber existing entry, count remains unchanged
          ++modCount;
          enqueueNotification(key, hash, entryValue, valueReference.getWeight(), RemovalCause.REPLACED);
          setValue(e, key, value, now);
          evictEntries(e);
          return entryValue;
        }
      }
    }

    // Create a new entry.

    ++modCount;
    ReferenceEntry<K, V> newEntry = newEntry(key, hash, first);
    setValue(newEntry, key, value, now);
    table.set(index, newEntry);
    newCount = this.count + 1;
    this.count = newCount; // write-volatile
    evictEntries(newEntry);
    return null;
  } finally {
    unlock();
    postWriteCleanup();
  }
}
 
源代码19 项目: codebuff   文件: LocalCache.java
@Nullable
V put(K key, int hash, V value, boolean onlyIfAbsent) {
  lock();
  try {
    long now = map.ticker.read();
    preWriteCleanup(now);
    int newCount = this.count + 1;
    if (newCount > this.threshold) { // ensure capacity
      expand();
      newCount = this.count + 1;
    }
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);

    // Look for an existing entry.
    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        // We found an existing entry.
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        if (entryValue == null) {
          ++modCount;
          if (valueReference.isActive()) {
            enqueueNotification(key, hash, entryValue, valueReference.getWeight(), RemovalCause.COLLECTED);
            setValue(e, key, value, now);
            newCount = this.count; // count remains unchanged
          } else {
            setValue(e, key, value, now);
            newCount = this.count + 1;
          }
          this.count = newCount; // write-volatile
          evictEntries(e);
          return null;
        }
        else if (onlyIfAbsent) {
          // Mimic
          // "if (!map.containsKey(key)) ...
          // else return map.get(key);
          recordLockedRead(e, now);
          return entryValue;
        } else {
          // clobber existing entry, count remains unchanged
          ++modCount;
          enqueueNotification(key, hash, entryValue, valueReference.getWeight(), RemovalCause.REPLACED);
          setValue(e, key, value, now);
          evictEntries(e);
          return entryValue;
        }
      }
    }

    // Create a new entry.

    ++modCount;
    ReferenceEntry<K, V> newEntry = newEntry(key, hash, first);
    setValue(newEntry, key, value, now);
    table.set(index, newEntry);
    newCount = this.count + 1;
    this.count = newCount; // write-volatile
    evictEntries(newEntry);
    return null;
  } finally {
    unlock();
    postWriteCleanup();
  }
}
 
源代码20 项目: codebuff   文件: LocalCache.java
boolean storeLoadedValue(K key, int hash, LoadingValueReference<K, V> oldValueReference, V newValue) {
  lock();
  try {
    long now = map.ticker.read();
    preWriteCleanup(now);
    int newCount = this.count + 1;
    if (newCount > this.threshold) { // ensure capacity
      expand();
      newCount = this.count + 1;
    }
    AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<K, V> first = table.get(index);
    for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) {
      K entryKey = e.getKey();
      if (e.getHash() == hash && entryKey != null
          && map.keyEquivalence.equivalent(key, entryKey)) {
        ValueReference<K, V> valueReference = e.getValueReference();
        V entryValue = valueReference.get();
        // replace the old LoadingValueReference if it's live, otherwise
        // perform a putIfAbsent
        if (oldValueReference == valueReference
            || (entryValue == null && valueReference != UNSET)) {
          ++modCount;
          if (oldValueReference.isActive()) {
            RemovalCause cause = (entryValue == null) ? RemovalCause.COLLECTED : RemovalCause.REPLACED;
            enqueueNotification(key, hash, entryValue, oldValueReference.getWeight(), cause);
            newCount--;
          }
          setValue(e, key, newValue, now);
          this.count = newCount; // write-volatile
          evictEntries(e);
          return true;
        }

        // the loaded value was already clobbered
        enqueueNotification(key, hash, newValue, 0, RemovalCause.REPLACED);
        return false;
      }
    }

    ++modCount;
    ReferenceEntry<K, V> newEntry = newEntry(key, hash, first);
    setValue(newEntry, key, newValue, now);
    table.set(index, newEntry);
    this.count = newCount; // write-volatile
    evictEntries(newEntry);
    return true;
  } finally {
    unlock();
    postWriteCleanup();
  }
}