Java并发编程之原子操作类详情

网友投稿 592 2022-10-11

Java并发编程之原子操作类详情

我们先来看一下部分源码:

public class AtomicLong extends Number implements java.io.Serializable {

private static final long serialVersionUID = 1927816293512124184L;

//1.获取Unsafe类实例

private static final Unsafe unsafe = Unsafe.getUnsafe();

//2.存放value的偏移量

private static final long valueOffset;

static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();

//3.用于判断是否支持Long类型无锁CAS

private static naJHgDqtive boolean VMSupportsCS8();

static {

try {

//4.获取value在AtomicLong中的偏移量

valueOffset = unsafe.objectFieldOffset

(AtomicLong.class.getDeclaredField("value"));

} catch (Exception ex) { throw new Error(ex); }

}

//5.实际变量值

private volatile long value;

/**

* Creates a new AtomicLong with the given initial value.

*

* @param initialValue the initial value

*/

public AtomicLong(long initialValue) {

value = initialValue;

}

省略部分代码

}

上面代码中,代码1处通过Unsafe.getUnsafe()获取到Unsafe类的实例(因为AtomicLong类是在rt.jar包下面的,AtomicLong类就是通过Bootstarp类加载器进行加载的)。代码5处,value被声明为volatile类型,保证内存的可见性。通过代码2,4获取value变量在AtomicLong类中的偏移量。

接下来介绍一下AtomicLong中的主要函数:

递增和递减代码

//调用unsafe方法,设置value=value+1后,返回原始的值

public final long getAndIncrement() {

return unsafe.getAndAddLong(this, valueOffset, 1L);

}

//调用unsafe方法,设置value=value-1后,返回原始的值

public final long getAndDecrement() {

return unsafe.getAndAddLong(this, valueOffset, -1L);

}

//调用unsafe方法,设置value=value+1后,返回递增后的值

public final long incrementAndGet() {

return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;

}

//调用unsafe方法,设置value=value-1后,返回递减后的值

public final long decrementAndGet() {

return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L;

}

上面的四个函数内部都是通过调用Unsafe的getAndAddLong方法来实现操作,这个函数是个原子性操作,这里第一个参数是AtomicLong实例的引用的,第二个参数是value变量在AtomicLong的偏移值,第三个参数是要设置的第二个变量的值。

其中getAndIncrement()方法在JDK7中实现逻辑为:

public final long getAndIncrement() {

while(true) {

long current = get();

long next = current + 1;

if (compareAndSet(current, next))

return current;

}

}

如上代码中,每个线程是先拿到变量的当前值(由于value是volatile变量,所以这是获取的最新值),然后在工作内存中对其进行增1操作,而后使用CAS修改变量的值,如果设置失败,则循环继续尝试,直到设置成功。

JDK8中的逻辑为:

public final long getAndIncrement() {

retrturn unsafe.getAndAddLong(this, valueOffset, 1L);http://

}

其中JDK8中的unsafe.getAndAddLong的代码为:

public final long getAndAddLong(Object var1, long var2, long var4) {

long var6;

do {

var6 = this.getLongVolatile(var1, var2);

} while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));

return var6;

}

从中可以看到,JDK7中的AtomicLong中循环逻辑已经被JDK8中的原子操作类Unsafe内置了。

boolean compareAndSet(long expect,long update)

public final boolean compareAndSet(long expect,long update)

{

return unsafe.compareAndSwapLong(this, valueOffset, expect, update);

}

函数在内部调用了unsafe.compareAndSwapLong方法。如果原子变量中的value值等于expect,则使用update值更新该值并返回true,否则返回false。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:PostGIS批量导入栅格数据
下一篇:对原生小程序开发进行简单的扩展封装(微信小程序 封装)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~