下面列出了java.util.concurrent.atomic.AtomicLongArray#get() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
long changeWord(int bitIndex, @Nonnull TLongFunction change) {
if (bitIndex < 0) {
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
}
AtomicLongArray array = getOrCreateArray(bitIndex);
int wordIndexInArray = wordIndexInArray(bitIndex);
long word;
long newWord;
do {
word = array.get(wordIndexInArray);
newWord = change.execute(word);
}
while (!array.compareAndSet(wordIndexInArray, word, newWord));
return word;
}
public void set(int position) {
int segmentPosition = position >>> log2SegmentSize; /// which segment -- div by num bits per segment
int longPosition = (position >>> 6) & segmentMask; /// which long in the segment -- remainder of div by num bits per segment
int bitPosition = position & 0x3F; /// which bit in the long -- remainder of div by num bits in long (64)
AtomicLongArray segment = getSegment(segmentPosition);
long mask = 1L << bitPosition;
// Thread safety: we need to loop until we win the race to set the long value.
while(true) {
// determine what the new long value will be after we set the appropriate bit.
long currentLongValue = segment.get(longPosition);
long newLongValue = currentLongValue | mask;
// if no other thread has modified the value since we read it, we won the race and we are done.
if(segment.compareAndSet(longPosition, currentLongValue, newLongValue))
break;
}
}
public void clear(int position) {
int segmentPosition = position >>> log2SegmentSize; /// which segment -- div by num bits per segment
int longPosition = (position >>> 6) & segmentMask; /// which long in the segment -- remainder of div by num bits per segment
int bitPosition = position & 0x3F; /// which bit in the long -- remainder of div by num bits in long (64)
AtomicLongArray segment = getSegment(segmentPosition);
long mask = ~(1L << bitPosition);
// Thread safety: we need to loop until we win the race to set the long value.
while(true) {
// determine what the new long value will be after we set the appropriate bit.
long currentLongValue = segment.get(longPosition);
long newLongValue = currentLongValue & mask;
// if no other thread has modified the value since we read it, we won the race and we are done.
if(segment.compareAndSet(longPosition, currentLongValue, newLongValue))
break;
}
}
public long maxSetBit() {
ThreadSafeBitSetSegments segments = this.segments.get();
int segmentIdx = segments.numSegments() - 1;
for(;segmentIdx >= 0; segmentIdx--) {
AtomicLongArray segment = segments.getSegment(segmentIdx);
for(int longIdx=segment.length() - 1; longIdx >= 0; longIdx--) {
long l = segment.get(longIdx);
if(l != 0)
return (segmentIdx << log2SegmentSize) + (longIdx * 64) + (63 - Long.numberOfLeadingZeros(l));
}
}
return -1;
}
@Override
public void request(long n) {
if (Operators.validate(n)) {
AtomicLongArray ra = parent.requests;
for (;;) {
long r = ra.get(index);
if (r == Long.MAX_VALUE) {
return;
}
long u = Operators.addCap(r, n);
if (ra.compareAndSet(index, r, u)) {
break;
}
}
if (parent.subscriberCount == length) {
parent.drain();
}
}
}
public long poll(boolean[] hasValue) {
final AtomicLongArray a = buffer;
final int m = mask;
final long ci = a.get(1);
int offset = calcOffset(ci, m);
int offset1 = offset + 1;
long v = a.get(offset1);
if (v == 0L) {
hasValue[0] = false;
return 0L;
}
hasValue[0] = true;
v = a.get(offset);
a.lazySet(offset1, 0L);
a.lazySet(1, ci + 2);
return v;
}
public long poll() {
final AtomicLongArray a = buffer;
final int m = mask;
final long ci = a.get(1);
int offset = calcOffset(ci, m);
long v = a.get(offset + 1);
if (v == 0L) {
return 0L;
}
v = a.get(offset);
a.lazySet(offset + 1, 0L);
a.lazySet(1, ci + 2);
return v;
}
private List<CountAtBucket> nonZeroBuckets() {
List<CountAtBucket> buckets = new ArrayList<>();
long zeroSnap = zeros.get();
if (zeroSnap > 0) {
buckets.add(new CountAtBucket(UPPER_BOUNDS[getRangeIndex(ZERO.bucketIdx, ZERO.offset)], zeroSnap));
}
long lowerSnap = lower.get();
if (lowerSnap > 0) {
buckets.add(new CountAtBucket(UPPER_BOUNDS[getRangeIndex(LOWER.bucketIdx, LOWER.offset)], lowerSnap));
}
long upperSnap = upper.get();
if (upperSnap > 0) {
buckets.add(new CountAtBucket(UPPER_BOUNDS[getRangeIndex(UPPER.bucketIdx, UPPER.offset)], upperSnap));
}
for (int i = 0; i < values.length(); i++) {
AtomicLongArray bucket = values.get(i);
if (bucket != null) {
for (int j = 0; j < bucket.length(); j++) {
long cnt = bucket.get(j);
if (cnt > 0) {
buckets.add(new CountAtBucket(UPPER_BOUNDS[getRangeIndex(i, j)], cnt));
}
}
}
}
return buckets;
}
/** Returns an {@link AtomicLongArray} array as a string, but does not print trailing zeroes.
*
* @param a an atomic array.
* @return {@link Arrays#toString(long[])} of {@code a}, but without trailing zeroes.
*/
public static String toString(final AtomicLongArray a) {
int i;
for(i = a.length(); i-- != 0;) if (a.get(i) != 0) break;
final long[] b = new long[i + 1];
for(++i; i-- != 0;) b[i] = a.get(i);
return Arrays.toString(b);
}
public boolean get(int position) {
int segmentPosition = position >>> log2SegmentSize; /// which segment -- div by num bits per segment
int longPosition = (position >>> 6) & segmentMask; /// which long in the segment -- remainder of div by num bits per segment
int bitPosition = position & 0x3F; /// which bit in the long -- remainder of div by num bits in long (64)
AtomicLongArray segment = getSegment(segmentPosition);
long mask = 1L << bitPosition;
return ((segment.get(longPosition) & mask) != 0);
}
public int nextSetBit(int fromIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
int segmentPosition = fromIndex >>> log2SegmentSize; /// which segment -- div by num bits per segment
ThreadSafeBitSetSegments segments = this.segments.get();
if(segmentPosition >= segments.numSegments())
return -1;
int longPosition = (fromIndex >>> 6) & segmentMask; /// which long in the segment -- remainder of div by num bits per segment
int bitPosition = fromIndex & 0x3F; /// which bit in the long -- remainder of div by num bits in long (64)
AtomicLongArray segment = segments.getSegment(segmentPosition);
long word = segment.get(longPosition) & (0xffffffffffffffffL << bitPosition);
while (true) {
if (word != 0)
return (segmentPosition << (log2SegmentSize)) + (longPosition << 6) + Long.numberOfTrailingZeros(word);
if (++longPosition > segmentMask) {
segmentPosition++;
if(segmentPosition >= segments.numSegments())
return -1;
segment = segments.getSegment(segmentPosition);
longPosition = 0;
}
word = segment.get(longPosition);
}
}
private static long[] toArray(AtomicLongArray a)
{
final long[] r = new long[a.length()];
for (int i = 0 ; i < r.length ; i++)
r[i] = a.get(i);
return r;
}
long getWord(int bitIndex) {
if (bitIndex < 0) {
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
}
int arrayIndex = arrayIndex(bitIndex);
AtomicLongArray array = arrays.get(arrayIndex);
if (array == null) {
return 0;
}
int wordIndexInArray = wordIndexInArray(bitIndex);
return array.get(wordIndexInArray);
}
@Override
protected final void _incDouble(int offset, double delta) {
final AtomicLongArray doubleStorage = this.doubleStorage;
while (true) {
final long longValue = doubleStorage.get(offset);
final long newValue = Double.doubleToLongBits(Double
.longBitsToDouble(longValue) + delta);
if (doubleStorage.compareAndSet(offset, longValue, newValue)) {
return;
}
}
}
/**
* Returns the index of the first bit that is set to {@code false}
* that occurs on or after the specified starting index.
*
* @param fromIndex the index to start checking from (inclusive)
* @return the index of the next clear bit
* @throws IndexOutOfBoundsException if the specified index is negative
*/
public int nextClearBit(int fromIndex) {
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
}
int arrayIndex = arrayIndex(fromIndex);
AtomicLongArray array = arrays.get(arrayIndex);
int wordIndexInArray = wordIndexInArray(fromIndex);
if (array == null) {
return ((1<<arrayIndex)-1+wordIndexInArray) * BITS_PER_WORD+(fromIndex%BITS_PER_WORD);
}
long word = ~array.get(wordIndexInArray) & (WORD_MASK << fromIndex);
while (true) {
if (word != 0) {
return ((1<<arrayIndex)-1 + wordIndexInArray) * BITS_PER_WORD + Long.numberOfTrailingZeros(word);
}
if (++wordIndexInArray == array.length()) {
wordIndexInArray = 0;
if (++arrayIndex == arrays.length()) return -1;
array = arrays.get(arrayIndex);
if (array == null) {
return ((1<<arrayIndex)-1+wordIndexInArray) * BITS_PER_WORD;
}
}
word = ~array.get(wordIndexInArray);
}
}
/**
* Returns the index of the first bit that is set to {@code true}
* that occurs on or after the specified starting index. If no such
* bit exists then {@code -1} is returned.
* <p/>
* <p>To iterate over the {@code true} bits,
* use the following loop:
* <p/>
* <pre> {@code
* for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
* // operate on index i here
* }}</pre>
*
* @param fromIndex the index to start checking from (inclusive)
* @return the index of the next set bit, or {@code -1} if there
* is no such bit
* @throws IndexOutOfBoundsException if the specified index is negative
*/
public int nextSetBit(int fromIndex) {
if (fromIndex < 0) {
throw new IndexOutOfBoundsException("bitIndex < 0: " + fromIndex);
}
int arrayIndex;
AtomicLongArray array = null;
for (arrayIndex = arrayIndex(fromIndex); arrayIndex < arrays.length() && (array = arrays.get(arrayIndex)) == null; arrayIndex++);
if (array == null) {
return -1;
}
int wordIndexInArray = wordIndexInArray(fromIndex);
long word = array.get(wordIndexInArray) & (WORD_MASK << fromIndex);
while (true) {
if (word != 0) {
return ((1<<arrayIndex)-1 + wordIndexInArray) * BITS_PER_WORD + Long.numberOfTrailingZeros(word);
}
if (++wordIndexInArray == array.length()) {
wordIndexInArray = 0;
for (++arrayIndex; arrayIndex != arrays.length() && (array = arrays.get(arrayIndex)) == null; arrayIndex++);
if (array == null) {
return -1;
}
}
word = array.get(wordIndexInArray);
}
}
@Override
protected final void _incDouble(int offset, double delta) {
final AtomicLongArray doubleStorage = this.doubleStorage;
while (true) {
final long longValue = doubleStorage.get(offset);
final long newValue = Double.doubleToLongBits(Double
.longBitsToDouble(longValue) + delta);
if (doubleStorage.compareAndSet(offset, longValue, newValue)) {
return;
}
}
}
@Nonnull
public long[] toLongArray() {
int bits = size();
long[] result = new long[bits/BITS_PER_WORD];
int i = 0;
for (int b=0; b<bits;b += BITS_PER_WORD){
AtomicLongArray array = arrays.get(arrayIndex(b));
long word = array == null ? 0 : array.get(wordIndexInArray(b));
result[i++] = word;
}
return result;
}
protected static long lvValue(AtomicLongArray elements, int index)
{
return elements.get(calcValueOffset(index));
}
protected final long lvSequence(AtomicLongArray buffer, int offset)
{
return buffer.get(offset);
}