# AtomicInteger实现
// AtomicInteger.java
public final int incrementAndGet() {
//如果写入失败,死循环重试
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
public final boolean compareAndSet(int expect, int update) {
//调用Unsafe类提供的native方法
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
// Unsage.java
public final native boolean compareAndSwapInt(Object target, long offset, int expect, int value);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 示例:直接使用Unsafe修改对象属性
public class T06_UnsafeSwap {
int value;
public static void main(String[] args) throws Exception {
//构造方法私有,通过反射获取实例
Field unsafeField = Unsafe.class.getDeclaredFields()[0];
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
//获取value的offset
Field field = T06_UnsafeSwap.class.getDeclaredField("value");
long offset = unsafe.objectFieldOffset(field);
System.out.println(offset);
//执行CAS操作
T06_UnsafeSwap target = new T06_UnsafeSwap();
boolean result = unsafe.compareAndSwapInt(target, offset, 0, 1);
System.out.println(result);
System.out.println(target.value);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# JDK8中unsafe的实现
unsafe.cpp
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj);
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END
1
2
3
4
5
6
2
3
4
5
6
cmpxchg: compare and exchange set swap
atomic_linux_x86.inline.hpp
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "cc", "memory");
return exchange_value;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
os.hpp is_MP()
static inline bool is_MP() {
// During bootstrap if _processor_count is not yet initialized
// we claim to be MP as that is safest. If any platform has a
// stub generator that might be triggered in this phase and for
// which being declared MP when in fact not, is a problem - then
// the bootstrap routine for the stub generator needs to check
// the processor count directly and leave the bootstrap routine
// in place until called after initialization has ocurred.
return (_processor_count != 1) || AssumeMP;
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
LOCK_IF_MP 判断是否拥有多个逻辑CPU,如果是,需要加锁。
加锁的方式是给cmpxchg指令前曾加lock指令。
lock指令会在执行的时候视情况采用缓存锁或者总线锁。
最终执行:lock cmpxchg 指令