一些先验知识:
volatile变量:
对该变量直接从主内存读取,保证是最新的。 通过内存屏障(Memory Barrier),对一个volatile变量的写操作以及这个写操作之前的所有操作happens-before对这个volatile变量的读操作以及读操作之后的所有操作。 有关Load Store屏障详见博客
happens-before:
定义:If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
如果A happens-before B,那么A的操作对B是可见的。
要注意的是happens-before和重排序无关: It should be noted that the presence of a happens-before relationship between two actions does not necessarily imply that they have to take place in that order in an implementation. If the reordering produces results consistent with a legal execution, it is not illegal.
AtomicInteger中只有一个volatile的变量value :
private volatile int value;
主要分为下面5个方法:
get has the memory effects of reading a volatile variable.
/**
* Gets the current value.
*
* @return the current value
*/
public final int get() {
return value;
}
set has the memory effects of writing (assigning) a volatile variable.
/**
* Sets to the given value.
*
* @param newValue the new value
*/
public final void set(int newValue) {
value = newValue;
}
set是原子性的,但是不需要之前之前的值,如果用在复合操作中,可能会有错误。
lazySet has the memory effects of writing (assigning) a volatile variable except that it permits reorderings with subsequent (but not previous) memory actions that do not themselves impose reordering constraints with ordinary non-volatile writes. Among other usage contexts, lazySet may apply when nulling out, for the sake of garbage collection, a reference that is never accessed again.
/**
* Eventually sets to the given value.
*
* @param newValue the new value
* @since 1.6
*/
public final void lazySet(int newValue) {
unsafe.putOrderedInt(this, valueOffset, newValue);
}
lazySet允许和之后的操作重排序,但是不能和它前面的操作重排序,详见Bug 6275329。可以用来将非阻塞结构的节点设为null,但是如果其他线程在这之前看到的是非null值也没关系的情况。lazySet在源码的注释是:Eventually sets to the given value。
weakCompareAndSet atomically reads and conditionally writes a variable but does not create any happens-before orderings, so provides no guarantees with respect to previous or subsequent reads and writes of any variables other than the target of the weakCompareAndSet.
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* <p><a href="package-summary.html#weakCompareAndSet">May fail
* spuriously and does not provide ordering guarantees</a>, so is
* only rarely an appropriate alternative to {@code compareAndSet}.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful
*/
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
weakCompareAndSet没有确保happens-before关系,因此它做的修改可能在其他线程中不可见,而且在expect满足条件时也可能会失败。参考Stackoverflow
但是现在weakCompareAndSet在源码中和compareAndSet是完全一样的。参考Stackoverflow
compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables.
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}