compareAndSet()源码实例Demo

java.util.concurrent.atomic.AtomicInteger#compareAndSet()源码实例Demo

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

源代码1 项目: akarnokd-misc   文件: QueueDrainAsyncPerf.java
@Group("g4")
@GroupThreads(2)
@Benchmark
public void queueDrainAtomic4() {
    AtomicInteger w = wip;
    if (w.getAndIncrement() == 0) {
        int missed = 1;

        for (;;) {
            counter++;

            if (w.compareAndSet(missed, 0)) {
                break;
            }
            missed = w.get();
        }
    }
}
 
源代码2 项目: akarnokd-misc   文件: QueueDrainPerf.java
@Benchmark
public void queueDrainAtomic4() {
    AtomicInteger w = wip;
    if (w.getAndIncrement() == 0) {
        int missed = 1;

        for (;;) {
            counter++;

            if (w.compareAndSet(missed, 0)) {
                break;
            }
            missed = w.get();
        }
    }
}
 
/**
 * Attempts to increment the given AtomicInteger without exceeding the
 * specified maximum value. If the AtomicInteger cannot be incremented
 * without exceeding the maximum, false is returned.
 *
 * @param counter
 *     The AtomicInteger to attempt to increment.
 *
 * @param max
 *     The maximum value that the given AtomicInteger should contain, or
 *     zero if no limit applies.
 *
 * @return
 *     true if the AtomicInteger was successfully incremented without
 *     exceeding the specified maximum, false if the AtomicInteger could
 *     not be incremented.
 */
private boolean tryIncrement(AtomicInteger counter, int max) {

    // Repeatedly attempt to increment the given AtomicInteger until we
    // explicitly succeed or explicitly fail
    while (true) {

        // Get current value
        int count = counter.get();

        // Bail out if the maximum has already been reached
        if (count >= max && max != 0)
            return false;

        // Attempt to increment
        if (counter.compareAndSet(count, count+1))
            return true;

        // Try again if unsuccessful

    }

}
 
源代码4 项目: kylin-on-parquet-v2   文件: QueryRequestLimits.java
static boolean openQueryRequest(String project, int maxConcurrentQuery) {
    if (maxConcurrentQuery == 0) {
        return true;
    }
    try {
        AtomicInteger nRunningQueries = runningStats.get(project);
        for (;;) {
            int nRunning = nRunningQueries.get();
            if (nRunning < maxConcurrentQuery) {
                if (nRunningQueries.compareAndSet(nRunning, nRunning + 1)) {
                    return true;
                }
            } else {
                return false;
            }
        }
    } catch (ExecutionException e) {
        throw new RuntimeException(e);
    }
}
 
@AfterClass
public static void end() throws InterruptedException{
	AtomicInteger mutex = new AtomicInteger(objectsToDelete.size());
	for(ObjectToDelete o : objectsToDelete){
		DBManager.deleteObject(o.getClassName(),o.getKey(),new DeleteCallback() {

			@Override
			public void done(ParseException arg0) {
				synchronized (mutex) {
					mutex.decrementAndGet();
				}
				
			}});
	}
	while (!mutex.compareAndSet(0, 0));
}
 
/**
 * Attempts to increment the given AtomicInteger without exceeding the
 * specified maximum value. If the AtomicInteger cannot be incremented
 * without exceeding the maximum, false is returned.
 *
 * @param counter
 *     The AtomicInteger to attempt to increment.
 *
 * @param max
 *     The maximum value that the given AtomicInteger should contain, or
 *     zero if no limit applies.
 *
 * @return
 *     true if the AtomicInteger was successfully incremented without
 *     exceeding the specified maximum, false if the AtomicInteger could
 *     not be incremented.
 */
private boolean tryIncrement(AtomicInteger counter, int max) {

    // Repeatedly attempt to increment the given AtomicInteger until we
    // explicitly succeed or explicitly fail
    while (true) {

        // Get current value
        int count = counter.get();

        // Bail out if the maximum has already been reached
        if (count >= max && max != 0)
            return false;

        // Attempt to increment
        if (counter.compareAndSet(count, count+1))
            return true;

        // Try again if unsuccessful

    }

}
 
源代码7 项目: codebuff   文件: ConcurrentHashMultiset.java
/**
 * Removes a number of occurrences of the specified element from this multiset. If the multiset
 * contains fewer than this number of occurrences to begin with, all occurrences will be removed.
 *
 * @param element the element whose occurrences should be removed
 * @param occurrences the number of occurrences of the element to remove
 * @return the count of the element before the operation; possibly zero
 * @throws IllegalArgumentException if {@code occurrences} is negative
 */
/*
 * TODO(cpovirk): remove and removeExactly currently accept null inputs only
 * if occurrences == 0. This satisfies both NullPointerTester and
 * CollectionRemoveTester.testRemove_nullAllowed, but it's not clear that it's
 * a good policy, especially because, in order for the test to pass, the
 * parameter must be misleadingly annotated as @Nullable. I suspect that
 * we'll want to remove @Nullable, add an eager checkNotNull, and loosen up
 * testRemove_nullAllowed.
 */

@CanIgnoreReturnValue
@Override
public int remove(@Nullable Object element, int occurrences) {
  if (occurrences == 0) {
    return count(element);
  }
  CollectPreconditions.checkPositive(occurrences, "occurences");
  AtomicInteger existingCounter = Maps.safeGet(countMap, element);
  if (existingCounter == null) {
    return 0;
  }
  while (true) {
    int oldValue = existingCounter.get();
    if (oldValue != 0) {
      int newValue = Math.max(0, oldValue - occurrences);
      if (existingCounter.compareAndSet(oldValue, newValue)) {
        if (newValue == 0) {
          // Just CASed to 0; remove the entry to clean up the map. If the removal fails,
          // another thread has already replaced it with a new counter, which is fine.
          countMap.remove(element, existingCounter);
        }
        return oldValue;
      }
    } else {
      return 0;
    }
  }
}
 
源代码8 项目: gemfirexd-oss   文件: GFXDServiceImpl.java
private static int getNextId(final AtomicInteger id) {
  while (true) {
    int currentId = id.get();
    int nextId = currentId + 1;
    if (nextId == INVALID_ID) {
      nextId++;
    }
    if (id.compareAndSet(currentId, nextId)) {
      return currentId;
    }
  }
}
 
源代码9 项目: ignite   文件: GridUnsafeLru.java
/**
 * Atomically increments the given value by one, re-starting from 0 when the specified maximum is reached.
 *
 * @param value Value to increment.
 * @param max Maximum after reaching which the value is reset to 0.
 * @return Incremented value.
 */
private int incrementAndGet(AtomicInteger value, int max) {
    while (true) {
        int cur = value.get();
        int next = cur == max ? 0 : cur + 1;

        if (value.compareAndSet(cur, next))
            return next;
    }
}
 
源代码10 项目: ecp-uid   文件: CachedUidGeneratorTest.java
public int updateAndGet(AtomicInteger control) {
    int prev, next;
    do {
        prev = control.get();
        next = prev == SIZE ? SIZE : prev + 1;
    } while (!control.compareAndSet(prev, next));
    return next;
}
 
源代码11 项目: RxJava3-preview   文件: HalfSerializer.java
/**
 * Emits the given value if possible and terminates if there was an onComplete or onError
 * while emitting, drops the value otherwise.
 * @param <T> the value type
 * @param observer the target Observer to emit to
 * @param value the value to emit
 * @param wip the serialization work-in-progress counter/indicator
 * @param error the holder of Throwables
 */
public static <T> void onNext(Observer<? super T> observer, T value,
        AtomicInteger wip, AtomicThrowable error) {
    if (wip.get() == 0 && wip.compareAndSet(0, 1)) {
        observer.onNext(value);
        if (wip.decrementAndGet() != 0) {
            Throwable ex = error.terminate();
            if (ex != null) {
                observer.onError(ex);
            } else {
                observer.onComplete();
            }
        }
    }
}
 
源代码12 项目: codebuff   文件: ConcurrentHashMultiset.java
/**
 * Removes exactly the specified number of occurrences of {@code element}, or makes no
 * change if this is not possible.
 *
 * <p>This method, in contrast to {@link #remove(Object, int)}, has no effect when the
 * element count is smaller than {@code occurrences}.
 *
 * @param element the element to remove
 * @param occurrences the number of occurrences of {@code element} to remove
 * @return {@code true} if the removal was possible (including if {@code occurrences} is zero)
 * @throws IllegalArgumentException if {@code occurrences} is negative
 */

@CanIgnoreReturnValue
public boolean removeExactly(@Nullable Object element, int occurrences) {
  if (occurrences == 0) {
    return true;
  }
  CollectPreconditions.checkPositive(occurrences, "occurences");
  AtomicInteger existingCounter = Maps.safeGet(countMap, element);
  if (existingCounter == null) {
    return false;
  }
  while (true) {
    int oldValue = existingCounter.get();
    if (oldValue < occurrences) {
      return false;
    }


    int newValue = oldValue - occurrences;
    if (existingCounter.compareAndSet(oldValue, newValue)) {
      if (newValue == 0) {
        // Just CASed to 0; remove the entry to clean up the map. If the removal fails,
        // another thread has already replaced it with a new counter, which is fine.
        countMap.remove(element, existingCounter);
      }
      return true;
    }
  }
}
 
源代码13 项目: openjdk-jdk9   文件: AtomicIntegerTest.java
/**
 * compareAndSet in one thread enables another waiting for value
 * to succeed
 */
public void testCompareAndSetInMultipleThreads() throws Exception {
    final AtomicInteger ai = new AtomicInteger(1);
    Thread t = new Thread(new CheckedRunnable() {
        public void realRun() {
            while (!ai.compareAndSet(2, 3))
                Thread.yield();
        }});

    t.start();
    assertTrue(ai.compareAndSet(1, 2));
    t.join(LONG_DELAY_MS);
    assertFalse(t.isAlive());
    assertEquals(3, ai.get());
}
 
源代码14 项目: lucene-solr   文件: TestIndexWriter.java
public void testRandomOperationsWithSoftDeletes() throws Exception {
  IndexWriterConfig iwc = newIndexWriterConfig();
  AtomicInteger seqNo = new AtomicInteger(-1);
  AtomicInteger retainingSeqNo = new AtomicInteger();
  iwc.setSoftDeletesField("soft_deletes");
  iwc.setMergePolicy(new SoftDeletesRetentionMergePolicy("soft_deletes",
      () -> LongPoint.newRangeQuery("seq_no", retainingSeqNo.longValue(), Long.MAX_VALUE), newMergePolicy()));
  try (Directory dir = newDirectory();
       IndexWriter writer = new IndexWriter(dir, iwc);
       SearcherManager sm = new SearcherManager(writer, new SearcherFactory())) {
    Semaphore numOperations = new Semaphore(10 + random().nextInt(1000));
    boolean singleDoc = random().nextBoolean();
    Thread[] threads = new Thread[1 + random().nextInt(4)];
    CountDownLatch latch = new CountDownLatch(threads.length);
    for (int i = 0; i < threads.length; i++) {
      threads[i] = new Thread(() -> {
        latch.countDown();
        try {
          latch.await();
          while (numOperations.tryAcquire()) {
            String id = singleDoc ? "1" : Integer.toString(random().nextInt(10));
            Document doc = new Document();
            doc.add(new StringField("id", id, Field.Store.YES));
            doc.add(new LongPoint("seq_no", seqNo.getAndIncrement()));
            if (random().nextInt(10) <= 2) {
              if (random().nextBoolean()) {
                doc.add(new NumericDocValuesField(iwc.softDeletesField, 1));
              }
              writer.softUpdateDocument(new Term("id", id), doc, new NumericDocValuesField(iwc.softDeletesField, 1));
            } else {
              writer.addDocument(doc);
            }
            if (random().nextInt(100) < 10) {
              int min = retainingSeqNo.get();
              int max = seqNo.get();
              if (min < max && random().nextBoolean()) {
                retainingSeqNo.compareAndSet(min, min - random().nextInt(max - min));
              }
            }
            if (random().nextInt(100) < 10) {
              sm.maybeRefreshBlocking();
            }
            if (random().nextInt(100) < 5) {
              writer.commit();
            }
            if (random().nextInt(100) < 1) {
              writer.forceMerge(1 + random().nextInt(10), random().nextBoolean());
            }
          }
        } catch (Exception e) {
          throw new AssertionError(e);
        }
      });
      threads[i].start();
    }
    for (Thread thread : threads) {
      thread.join();
    }
  }
}
 
源代码15 项目: codebuff   文件: ConcurrentHashMultiset.java
/**
 * Sets the number of occurrences of {@code element} to {@code newCount}, but only if
 * the count is currently {@code expectedOldCount}. If {@code element} does not appear
 * in the multiset exactly {@code expectedOldCount} times, no changes will be made.
 *
 * @return {@code true} if the change was successful. This usually indicates
 *     that the multiset has been modified, but not always: in the case that
 *     {@code expectedOldCount == newCount}, the method will return {@code true} if
 *     the condition was met.
 * @throws IllegalArgumentException if {@code expectedOldCount} or {@code newCount} is negative
 */

@CanIgnoreReturnValue
@Override
public boolean setCount(E element, int expectedOldCount, int newCount) {
  checkNotNull(element);
  checkNonnegative(expectedOldCount, "oldCount");
  checkNonnegative(newCount, "newCount");
  AtomicInteger existingCounter = Maps.safeGet(countMap, element);
  if (existingCounter == null) {
    if (expectedOldCount != 0) {
      return false;
    } else if (newCount == 0) {
      return true;
    } else {
      // if our write lost the race, it must have lost to a nonzero value, so we can stop
      return countMap.putIfAbsent(element, new AtomicInteger(newCount)) == null;
    }
  }


  int oldValue = existingCounter.get();
  if (oldValue == expectedOldCount) {
    if (oldValue == 0) {
      if (newCount == 0) {
        // Just observed a 0; try to remove the entry to clean up the map
        countMap.remove(element, existingCounter);
        return true;
      } else {
        AtomicInteger newCounter = new AtomicInteger(newCount);
        return (countMap.putIfAbsent(element, newCounter) == null)
          || countMap.replace(element, existingCounter, newCounter);
      }
    } else {
      if (existingCounter.compareAndSet(oldValue, newCount)) {
        if (newCount == 0) {
          // Just CASed to 0; remove the entry to clean up the map. If the removal fails,
          // another thread has already replaced it with a new counter, which is fine.
          countMap.remove(element, existingCounter);
        }
        return true;
      }
    }
  }
  return false;
}
 
源代码16 项目: codebuff   文件: ConcurrentHashMultiset.java
/**
 * Sets the number of occurrences of {@code element} to {@code newCount}, but only if
 * the count is currently {@code expectedOldCount}. If {@code element} does not appear
 * in the multiset exactly {@code expectedOldCount} times, no changes will be made.
 *
 * @return {@code true} if the change was successful. This usually indicates
 *     that the multiset has been modified, but not always: in the case that
 *     {@code expectedOldCount == newCount}, the method will return {@code true} if
 *     the condition was met.
 * @throws IllegalArgumentException if {@code expectedOldCount} or {@code newCount} is negative
 */

@CanIgnoreReturnValue
@Override
public boolean setCount(E element, int expectedOldCount, int newCount) {
  checkNotNull(element);
  checkNonnegative(expectedOldCount, "oldCount");
  checkNonnegative(newCount, "newCount");
  AtomicInteger existingCounter = Maps.safeGet(countMap, element);
  if (existingCounter == null) {
    if (expectedOldCount != 0) {
      return false;
    } else if (newCount == 0) {
      return true;
    } else {
      // if our write lost the race, it must have lost to a nonzero value, so we can stop
      return countMap.putIfAbsent(element, new AtomicInteger(newCount)) == null;
    }
  }


  int oldValue = existingCounter.get();
  if (oldValue == expectedOldCount) {
    if (oldValue == 0) {
      if (newCount == 0) {
        // Just observed a 0; try to remove the entry to clean up the map
        countMap.remove(element, existingCounter);
        return true;
      } else {
        AtomicInteger newCounter = new AtomicInteger(newCount);
        return (countMap.putIfAbsent(element, newCounter) == null)
          || countMap.replace(element, existingCounter, newCounter);
      }
    } else {
      if (existingCounter.compareAndSet(oldValue, newCount)) {
        if (newCount == 0) {
          // Just CASed to 0; remove the entry to clean up the map. If the removal fails,
          // another thread has already replaced it with a new counter, which is fine.
          countMap.remove(element, existingCounter);
        }
        return true;
      }
    }
  }
  return false;
}
 
@Benchmark
public void wipCas() {
    AtomicInteger v = value;
    int w = v.get();
    v.compareAndSet(w, w - 1);
}
 
源代码18 项目: codebuff   文件: ConcurrentHashMultiset.java
/**
 * Sets the number of occurrences of {@code element} to {@code newCount}, but only if
 * the count is currently {@code expectedOldCount}. If {@code element} does not appear
 * in the multiset exactly {@code expectedOldCount} times, no changes will be made.
 *
 * @return {@code true} if the change was successful. This usually indicates
 *     that the multiset has been modified, but not always: in the case that
 *     {@code expectedOldCount == newCount}, the method will return {@code true} if
 *     the condition was met.
 * @throws IllegalArgumentException if {@code expectedOldCount} or {@code newCount} is negative
 */

@CanIgnoreReturnValue
@Override
public boolean setCount(E element, int expectedOldCount, int newCount) {
  checkNotNull(element);
  checkNonnegative(expectedOldCount, "oldCount");
  checkNonnegative(newCount, "newCount");
  AtomicInteger existingCounter = Maps.safeGet(countMap, element);
  if (existingCounter == null) {
    if (expectedOldCount != 0) {
      return false;
    } else if (newCount == 0) {
      return true;
    } else {
      // if our write lost the race, it must have lost to a nonzero value, so we can stop
      return countMap.putIfAbsent(element, new AtomicInteger(newCount)) == null;
    }
  }


  int oldValue = existingCounter.get();
  if (oldValue == expectedOldCount) {
    if (oldValue == 0) {
      if (newCount == 0) {
        // Just observed a 0; try to remove the entry to clean up the map
        countMap.remove(element, existingCounter);
        return true;
      } else {
        AtomicInteger newCounter = new AtomicInteger(newCount);
        return (countMap.putIfAbsent(element, newCounter) == null)
          || countMap.replace(element, existingCounter, newCounter);
      }
    } else {
      if (existingCounter.compareAndSet(oldValue, newCount)) {
        if (newCount == 0) {
          // Just CASed to 0; remove the entry to clean up the map. If the removal fails,
          // another thread has already replaced it with a new counter, which is fine.
          countMap.remove(element, existingCounter);
        }
        return true;
      }
    }
  }
  return false;
}
 
源代码19 项目: codebuff   文件: ConcurrentHashMultiset.java
/**
 * Adds a number of occurrences of the specified element to this multiset.
 *
 * @param element the element to add
 * @param occurrences the number of occurrences to add
 * @return the previous count of the element before the operation; possibly zero
 * @throws IllegalArgumentException if {@code occurrences} is negative, or if
 *     the resulting amount would exceed {@link Integer#MAX_VALUE}
 */

@CanIgnoreReturnValue
@Override
public int add(E element, int occurrences) {
  checkNotNull(element);
  if (occurrences == 0) {
    return count(element);
  }
  CollectPreconditions.checkPositive(occurrences, "occurences");
  while (true) {
    AtomicInteger existingCounter = Maps.safeGet(countMap, element);
    if (existingCounter == null) {
      existingCounter = countMap.putIfAbsent(element, new AtomicInteger(occurrences));
      if (existingCounter == null) {
        return 0;
      }
      // existingCounter != null: fall through to operate against the existing AtomicInteger
    }
    while (true) {
      int oldValue = existingCounter.get();
      if (oldValue != 0) {
        try {
          int newValue = IntMath.checkedAdd(oldValue, occurrences);
          if (existingCounter.compareAndSet(oldValue, newValue)) {
            // newValue can't == 0, so no need to check & remove
            return oldValue;
          }
        } catch (ArithmeticException overflow) {
          throw new IllegalArgumentException("Overflow adding " + occurrences + " occurrences to a count of " + oldValue);
        }
      } else {
        // In the case of a concurrent remove, we might observe a zero value, which means another
        // thread is about to remove (element, existingCounter) from the map. Rather than wait,
        // we can just do that work here.
        AtomicInteger newCounter = new AtomicInteger(occurrences);
        if ((countMap.putIfAbsent(element, newCounter) == null)
            || countMap.replace(element, existingCounter, newCounter)) {
          return 0;
        }
        break;
      }
    }

    // If we're still here, there was a race, so just try again.
  }
}
 
源代码20 项目: codebuff   文件: ConcurrentHashMultiset.java
/**
 * Adds a number of occurrences of the specified element to this multiset.
 *
 * @param element the element to add
 * @param occurrences the number of occurrences to add
 * @return the previous count of the element before the operation; possibly zero
 * @throws IllegalArgumentException if {@code occurrences} is negative, or if
 *     the resulting amount would exceed {@link Integer#MAX_VALUE}
 */
@CanIgnoreReturnValue
@Override
public int add(E element, int occurrences) {
  checkNotNull(element);
  if (occurrences == 0) {
    return count(element);
  }
  CollectPreconditions.checkPositive(occurrences, "occurences");

  while (true) {
    AtomicInteger existingCounter = Maps.safeGet(countMap, element);
    if (existingCounter == null) {
      existingCounter = countMap.putIfAbsent(element, new AtomicInteger(occurrences));
      if (existingCounter == null) {
        return 0;
      }
      // existingCounter != null: fall through to operate against the existing AtomicInteger
    }

    while (true) {
      int oldValue = existingCounter.get();
      if (oldValue != 0) {
        try {
          int newValue = IntMath.checkedAdd(oldValue, occurrences);
          if (existingCounter.compareAndSet(oldValue, newValue)) {
            // newValue can't == 0, so no need to check & remove
            return oldValue;
          }
        } catch (ArithmeticException overflow) {
          throw new IllegalArgumentException(
              "Overflow adding " + occurrences + " occurrences to a count of " + oldValue);
        }
      } else {
        // In the case of a concurrent remove, we might observe a zero value, which means another
        // thread is about to remove (element, existingCounter) from the map. Rather than wait,
        // we can just do that work here.
        AtomicInteger newCounter = new AtomicInteger(occurrences);
        if ((countMap.putIfAbsent(element, newCounter) == null)
            || countMap.replace(element, existingCounter, newCounter)) {
          return 0;
        }
        break;
      }
    }

    // If we're still here, there was a race, so just try again.
  }
}