其实获得了 Unsafe 之后直接调 API 就行。
package dongguabai.atomic;
import org.springframework.objenesis.instantiator.util.UnsafeUtils;
import sun.misc.Unsafe;
/**
* @author Dongguabai
* @description
* @date 2021-02-21 19:53
*/
public class MyAtomicInteger {
private volatile int value;
private static final long valueOffset;
private static final Unsafe UNSAFE = UnsafeUtils.getUnsafe();
static {
try {
valueOffset = UNSAFE.objectFieldOffset(MyAtomicInteger.class.getDeclaredField("value"));
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
public final int incrementAndGet() {
return UNSAFE.getAndAddInt(this, valueOffset, 1) + 1;
}
public final int incrementAndGet2() {
int i;
while (true){
i = value+1;
if (UNSAFE.compareAndSwapInt(this,valueOffset,value,i)){
return i;
}
}
}
}
测试:
package dongguabai.atomic;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Dongguabai
* @description
* @date 2021-02-21 16:35
*/
public class AtomicIntegerDemo {
static int i ;
static AtomicInteger j = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
System.out.println("i++:");
for (int k = 0; k < 10; k++) {
new Thread(()-> System.out.println(++i)).start();
}
Thread.sleep(1000);
System.out.println("\nAtomicInteger:");
for (int k = 0; k < 10; k++) {
new Thread(()-> System.out.println(j.incrementAndGet())).start();
}
Thread.sleep(1000);
System.out.println("\nAtomicInteger:");
MyAtomicInteger myAtomicInteger = new MyAtomicInteger();
for (int k = 0; k < 10; k++) {
new Thread(()-> System.out.println(myAtomicInteger.incrementAndGet())).start();
}
Thread.sleep(1000);
System.out.println("\nAtomicInteger2:");
MyAtomicInteger myAtomicInteger2 = new MyAtomicInteger();
for (int k = 0; k < 10; k++) {
new Thread(()-> System.out.println(myAtomicInteger2.incrementAndGet2())).start();
}
}
}
输出结果:
i++:
1
2
3
4
5
6
7
8
9
10
AtomicInteger:
1
2
3
4
5
6
7
8
9
10
AtomicInteger:
1
2
3
4
5
6
7
8
9
10
AtomicInteger2:
1
2
3
4
5
6
7
8
9
10