; t[i] = new Thread() {
public void run() {
if (Math.random() > 0.4) {
scoreUpdater.incrementAndGet(stu);
allScore.incrementAndGet();
}
}
};
t[i].start();
}
for (int i = 0; i < 10000; i++) {
t[i].join();
}
System.out.println("score=" + stu.score);
System.out.println("allScore=" + allScore);
}
}
jdk中Vector是加锁的, 网上找的一个无锁Vector LockFreeVector, 给他添加了源码中文注释.
主要关注push_back, 添加元素的函数
import java.util.AbstractList;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
/**
* It is a thread safe and lock-free vector.
* This class implement algorithm from:<br>
*
* Lock-free Dynamically Resizable Arrays <br>
*
* @param <E> type of element in the vector
*
*/
public class LockFreeVector<E> extends AbstractList<E> {
private static final boolean debug = false;
/**
* Size of the first bucket. sizeof(bucket[i+1])=2*sizeof(bucket[i])
*/
private static final int FIRST_BUCKET_SIZE = 8;
/**
* number of buckets. 30 will allow 8*(2^30-1) elements
*/
private static final int N_BUCKET = 30;
/**
* We will have at most N_BUCKET number of buckets. And we have
* sizeof(buckets.get(i))=FIRST_BUCKET_SIZE**(i+1)
*
* 为什么AtomicReferenceArray里再套一个AtomicReferenceArray呢, 类似一个篮子(buckets)里放了很多篮子
* 为了在容量扩展时希望尽可能少的改动原有数据, 因此把一维数组扩展成二维数组.
* 该二维数组并非均衡的分布. 可能第一个数组8个元素, 第二个数组16个元素, 第三个数组32个......
*/
private final AtomicReferenceArray<AtomicReferenceArray<E>> buckets;
/**
* @param <E>
*/
static class WriteDescriptor<E> {
public E oldV;
public E newV;
public AtomicReferenceArray<E> addr;
public int addr_ind;
/**
* Creating a new descriptor.
*
* @param addr Operation address 对哪个数组进???写
* @param addr_ind Index of address 指定index
* @param oldV old operand
* @param newV new operand
*/
public WriteDescriptor(AtomicReferenceArray<E> addr, int addr_ind,
E oldV, E newV) {