/**
modCount记录每一次put,remove,clear,为了避免ABA问题。segment数据结构中,读数据不加锁,写数据加锁,在并发条件下,在size等统计方法中,存在在计算过程中,记录变化的可能。
**/
public boolean isEmpty() {
final Segment<K,V>[] segments = this.segments;
int[] mc = new int[segments.length];
int mcsum = 0;
for (int i = 0; i < segments.length; ++i) {
//有段中数据不为空,则map数据不为空
if (segments[i].count != 0)
return false;
else
mcsum += mc[i] = segments[i].modCount;
}
if (mcsum != 0) {
for (int i = 0; i < segments.length; ++i) {
if (segments[i].count != 0 ||
//说明数据段中已变化
mc[i] != segments[i].modCount)
return false;
}
}
return true;
}
/**
在无锁条件下尝试计算size,最多重复两次,如两次计算不成功,则在加锁条件下计算size。
**/
public int size() {
final Segment<K,V>[] segments = this.segments;
long sum = 0;
long check = 0;
int[] mc = new int[segments.length];
for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
check = 0;
sum = 0;
int mcsum = 0;
for (int i = 0; i < segments.length; ++i) {
sum += segments[i].count;
mcsum += mc[i] = segments[i].modCount;
}
if (mcsum != 0) {
for (int i = 0; i < segments.length; ++i) {
check += segments[i].count;
if (mc[i] != segments[i].modCount) {
check = -1; // force retry
break;
}
}
}
if (check == sum)
break;
}
if (check != sum) { // Resort to locking all segments
sum = 0;
for (int i = 0; i < segments.length; ++i)
segments[i].lock();
for (int i = 0; i < segments.length; ++i)
sum += segments[i].count;
for (int i = 0; i < segments.length; ++i)
segments[i].unlock();
}
if (sum > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
else
return (int)sum;
}