bsp; // 对于4来讲, 他就是00000000 00000000 00000000 00000100, 他的前导0 就是29
// 所以shift = 2
shift = 31 - Integer.numberOfLeadingZeros(scale);
}
// 获取第i个元素
public final int get(int i) {
return getRaw(checkedByteOffset(i));
}
// 第i个元素, 在数组中的偏移量是多少
private long checkedByteOffset(int i) {
if (i < 0 || i >= array.length)
throw new IndexOutOfBoundsException("index " + i);
return byteOffset(i);
}
// base : 数组基地址, i << shift, 其实就是i * 4, 因为这边是int array.
private static long byteOffset(int i) {
// i * 4 + base
return ((long) i << shift) + base;
}
// 根据偏移量从数组中获取数据
private int getRaw(long offset) {
return unsafe.getIntVolatile(array, offset);
}
Demo
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicArrayDemo {
static AtomicIntegerArray arr = new AtomicIntegerArray(10);
public static class AddThread implements Runnable {
public void run() {
for (int k = 0; k < 10000; k++) {
arr.incrementAndGet(k % arr.length());
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread[] ts = new Thread[10];
for (int k = 0; k < 10; k++) {
ts[k] = new Thread(new AddThread());
}
for (int k = 0; k < 10; k++) {
ts[k].start();
}
for (int k = 0; k < 10; k++) {
ts[k].join();
}
System.out.println(arr);
}
}
让普通变量也享受原子操作
主要接口
1 AtomicIntegerFieldUpdater.newUpdater()
2 incrementAndGet()
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class AtomicIntegerFieldUpdaterDemo {
public static class Candidate {
int id;
// 如果直接把int改成atomicinteger, 可能对代码破坏比较大
// 因此使用AtomicIntegerFieldUpdater对score进行封装
volatile int score;
}
// 通过反射实现
public final static AtomicIntegerFieldUpdater<Candidate> scoreUpdater = AtomicIntegerFieldUpdater.newUpdater(Candidate.class, "score");
// 检查Updater是否工作正确, allScore的结果应该跟score一致
public static AtomicInteger allScore = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
final Candidate stu = new Candidate();
Thread[] t = new Thread[10000];
for (int i = 0; i < 10000; i++) {