// 附上CAS 源码分析import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
AtomicInteger atomicInteger =new AtomicInteger(4);
atomicInteger.addAndGet(6);
}
}
//AtomicInteger.java: /*** Atomically adds the given value to the current value,* with memory effects as specified by {@link VarHandle#getAndAdd}.** @param delta the value to add* @return the updated value*/
public final int addAndGet(int delta) {
return U.getAndAddInt(this, VALUE, delta) + delta;
}
// Unsafe.java /*** Atomically adds the given value to the current value of a field* or array element within the given object {@code o}* at the given {@code offset}.** @param o object/array to update the field/element in* @param offset field/element offset* @param delta the value to add* @return the previous value* @since 1.8*/
@HotSpotIntrinsicCandidate
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
v = getIntVolatile(o, offset);
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
return v;
}
@HotSpotIntrinsicCandidate
public final boolean weakCompareAndSetInt(Object o, long offset,
int expected,
int x) {
return compareAndSetInt(o, offset, expected, x);
}
/*** Atomically updates Java variable to {@code x} if it is currently* holding {@code expected}.**
This operation has memory semantics of a {@code volatile} read* and write. Corresponds to C11 atomic_compare_exchange_strong.** @return {@code true} if successful*/
@HotSpotIntrinsicCandidate
public final native boolean compareAndSetInt(Object o, long offset,
int expected,
int x);
/** Volatile version of {@link #getInt(Object, long)} */
@HotSpotIntrinsicCandidate
public native int getIntVolatile(Object o, long offset);
static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
ScopedFastNativeObjectAccess soa(env);
ObjPtr<:object> obj = soa.Decode<:object>(javaObj);
return obj->GetField32Volatile(MemberOffset(offset));
}
template
ALWAYS_INLINE int32_t GetField32Volatile(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
return GetField32(field_offset);
}
template
ALWAYS_INLINE int32_t GetField32(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
Verify();
return GetFieldPrimitive(field_offset);
}
template
ALWAYS_INLINE kType GetFieldPrimitive(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
const uint8_t* raw_addr = reinterpret_cast(this) + field_offset.Int32Value();
const kType* addr = reinterpret_cast(raw_addr);
if (kIsVolatile) {
return reinterpret_cast*>(addr)->load(std::memory_order_seq_cst);
} else {
return reinterpret_cast*>(addr)->LoadJavaData();
}
// c++ atomic memory atomic memory order //http://senlinzhan.github.io/2017/12/04/cpp-memory-order/ // https://en.cppreference.com/w/cpp/atomic/memory_order
}
// 因为这里每次getIntVolatile获取此时此刻最新的值,所以当expected的值和getIntVolatile//得到的值不一样的时候,说明此时有其他线程在操作这个变量,说明存在竞争。(存在ABA问题,可增添每次的修改版本解决,暂无研究)
public boolean compareAndSetInt(@NotNull T owner, int expected, int newValue) {
return unsafe.compareAndSwapInt(owner, offset, expected, newValue);
}
//art/runtime/native/sun_misc_Unsafe.cc:static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
jint expectedValue, jint newValue) {
ScopedFastNativeObjectAccess soa(env);
ObjPtr<:object> obj = soa.Decode<:object>(javaObj);
// JNI must use non transactional mode. bool success = obj->CasField32(MemberOffset(offset),
expectedValue,
newValue,
CASMode::kStrong,
std::memory_order_seq_cst);
return success ? JNI_TRUE : JNI_FALSE;
}
template
inline bool Object::CasField32(MemberOffset field_offset,
int32_t old_value,
int32_t new_value,
CASMode mode,
std::memory_order memory_order) {
if (kCheckTransaction) {
DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
}
if (kTransactionActive) {
Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
}
if (kVerifyFlags & kVerifyThis) {
VerifyObject(this);
}
uint8_t* raw_addr = reinterpret_cast(this) + field_offset.Int32Value();
AtomicInteger* atomic_addr = reinterpret_cast(raw_addr);
return atomic_addr->CompareAndSet(old_value, new_value, mode, memory_order);
}
//art/libartbase/base/atomic.hbool CompareAndSet(T expected_value,
T desired_value,
CASMode mode,
std::memory_order memory_order) {
return mode == CASMode::kStrong
? this->compare_exchange_strong(expected_value, desired_value, memory_order)
: this->compare_exchange_weak(expected_value, desired_value, memory_order);
// external/libcxx/include/atomic bool compare_exchange_strong(_Tp& __e, _Tp __d,
memory_order __m = memory_order_seq_cst) _NOEXCEPT
{return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}