Java生成日期时间存入Mysql数据库的实现方法
274
2022-08-13
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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~