java怎么调用同包变量,Java并发包中的原子变量操作类

本文详细解析了Java并发包中的AtomicLong类,它利用CAS(Compare and Swap)非阻塞算法实现原子性操作,提高了并发性能。AtomicLong通过Unsafe类进行底层操作,提供如incrementAndGet()等方法实现线程安全的增减操作。同时,文章通过代码示例展示了如何在多线程环境下使用AtomicLong统计0的个数。
摘要由CSDN通过智能技术生成

AAffA0nNPuCLAAAAAElFTkSuQmCC

JUC并发包提供了一系列的原子操作类,这些类都是使用非阻塞算法(CAS)实现的,相比于使用锁来实现,这些原子操作类在性能上更好一些。

JUC并发包中包含有AtomicInteger、AtomicLong和AtomicBoolean等原子性操作类,它们的原理相似。

这里以AtomicLong为例进行说明,AtomicLong是原子性递增或者递减类,它是使用Unsafe来实现的。

AtomicLong通过CAS提供了非阻塞的原子性操作。

其源码如下:public class AtomicLong extends Number implements java.io.Serializable {

private static final long serialVersionUID = 1927816293512124184L;

// 1. 获取Unsafe实例 AtomicLong类是通过BootStarp类加载器进行加载的

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

// 2. 存放变量value的偏移量

private static final long valueOffset;

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

static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();

private static native boolean VMSupportsCS8();

static {

try {

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

valueOffset = unsafe.objectFieldOffset

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

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

}

// 5. 实际变量值,声明为volatile是为了在多线程环境下保证其内存可见性,value是具体存放计数的变量。

private volatile long value;

// 6. 有参构造方法

public AtomicLong(long initialValue) {

value = initialValue;

}

// 7. 无参构造方法

public AtomicLong() {

}

// 8. 获取值

public final long get() {

return value;

}

// 9. 写入值

public final void set(long newValue) {

value = newValue;

}

public final void lazySet(long newValue) {

unsafe.putOrderedLong(this, valueOffset, newValue);

}

public final long getAndSet(long newValue) {

return unsafe.getAndSetLong(this, valueOffset, newValue);

}

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

public final boolean compareAndSet(long expect, long update) {

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

}

//同上

public final boolean weakCompareAndSet(long expect, long update) {

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

}

// 调用unsafe方法,原子性设置value值为原始值+1,返回值为原始值

public final long getAndIncrement() {

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

}

// 调用unsafe方法,原子性设置value值为原始值-1,返回值为原始值

public final long getAndDecrement() {

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

}

// 调用unsafe方法,原子性设置value值加上delta,并返回

public final long getAndAdd(long delta) {

return unsafe.getAndAddLong(this, valueOffset, delta);

}

// 调用unsafe方法,原子性设置value值为原始值+1,返回值为递增后的值

public final long incrementAndGet() {

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

}

// 调用unsafe方法,原子性设置value值为原始值-1,返回值为递减后的值

public final long decrementAndGet() {

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

}

// 调用unsafe方法,原子性设置value值为原始值 + delta,返回值为加操作后的值

public final long addAndGet(long delta) {

return unsafe.getAndAddLong(this, valueOffset, delta) + delta;

}

public final long getAndUpdate(LongUnaryOperator updateFunction) {

long prev, next;

do {

prev = get();

next = updateFunction.applyAsLong(prev);

} while (!compareAndSet(prev, next));

return prev;

}

public final long updateAndGet(LongUnaryOperator updateFunction) {

long prev, next;

do {

prev = get();

next = updateFunction.applyAsLong(prev);

} while (!compareAndSet(prev, next));

return next;

}

public final long getAndAccumulate(long x,

LongBinaryOperator accumulatorFunction) {

long prev, next;

do {

prev = get();

next = accumulatorFunction.applyAsLong(prev, x);

} while (!compareAndSet(prev, next));

return prev;

}

public final long accumulateAndGet(long x,

LongBinaryOperator accumulatorFunction) {

long prev, next;

do {

prev = get();

next = accumulatorFunction.applyAsLong(prev, x);

} while (!compareAndSet(prev, next));

return next;

}

public String toString() {

return Long.toString(get());

}

// 获取int类型的值

public int intValue() {

return (int)get();

}

// 获取long类型的值

public long longValue() {

return get();

}

// 获取float类型的值

public float floatValue() {

return (float)get();

}

// 获取double类型的值

public double doubleValue() {

return (double)get();

}

}

从源码中看出,AtomicLong的递增或递减方法都是通过调用Unsafe的getAndAddLong方法来实现操作。

getAndAddLong方法是个原子性操作,在这里它的第一个参数是AtomicLong实例的引用,第二个参数是value变量在AtomicLong中的偏移量,第三个参数是要设置的第二个变量的值。

使用AtomicLong的实例代码见thread20

关于AtomicInteger和AtomicBoolean与AtomicLong原理类似,就不多说了。

代码示例:import java.util.concurrent.atomic.AtomicBoolean;

import java.util.concurrent.atomic.AtomicInteger;

import java.util.concurrent.atomic.AtomicLong;

/**

* @ClassName: AtomicLongTest

* @Description: 使用AtomicLong统计0的个数

* @Author: liuhefei

* @Date: 2019/12/8

* @blog: https://www.imooc.com/u/1323320/articles

**/

public class AtomicLongTest {

//1. 创建Long类型原子计数器

private static AtomicLong atomicLong = new AtomicLong();

//private static AtomicInteger atomicInteger = new AtomicInteger();

//private static AtomicBoolean atomicBoolean = new AtomicBoolean();

//2. 创建数据源

private static Integer[] arrayOne = new Integer[]{0, 1, 4, 0, 9, 100, 0, 1000, 54, 60, 20, 12, 0};

private static Integer[] arrayTwo = new Integer[]{0, 100, 30, 4, 6, 0, 8, 87, 0, 23, 56, 0, 3, 6 , 10, 0};

public static void main(String[] args) throws InterruptedException {

//线程one统计arrayOne中0的个数

Thread threadOne = new Thread(new Runnable() {

@Override

public void run() {

int size = arrayOne.length;

for(int i = 0; i 

if(arrayOne[i].intValue() == 0){

atomicLong.incrementAndGet();  //调用unsafe方法,原子性设置value值为原始值+1,并返回递增后的值

}

}

}

});

//线程two统计arrayTwo中0的个数

Thread threadTwo = new Thread(new Runnable() {

@Override

public void run() {

int size = arrayTwo.length;

for(int i = 0; i 

if(arrayTwo[i].intValue() == 0){

atomicLong.incrementAndGet();  //调用unsafe方法,原子性设置value值为原始值+1,并返回递增后的值

}

}

}

});

//启动线程

threadOne.start();

threadTwo.start();

//等待线程执行完毕

threadOne.join();

threadTwo.join();

System.out.println("count 0 = " + atomicLong.get());

}

}

发文不易,请诸君且看且点赞,感谢你的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值