加入收藏 | 设为首页 | 会员中心 | 我要投稿 惠州站长网 (https://www.0752zz.com.cn/)- 办公协同、云通信、物联设备、操作系统、高性能计算!
当前位置: 首页 > 业界 > 正文

推荐 7 个学习 TypeScript 的宝库

发布时间:2021-01-30 13:20:40 所属栏目:业界 来源:互联网
导读:这里我们发现 log.info(execute);,在代码中只执行了一次,并且 isHappened:true的值为true,这是为啥呢? 这里是因为当程序第一次 compareAndSet()的时候,使得 isHappend变为了true,因为原子性的关系,没有其他线程进行干扰,通过使用AtomicBoolean,我们使

这里我们发现 log.info("execute");,在代码中只执行了一次,并且 isHappened:true的值为true,这是为啥呢?

这里是因为当程序第一次 compareAndSet()的时候,使得 isHappend变为了true,因为原子性的关系,没有其他线程进行干扰,通过使用AtomicBoolean,我们使某段代码只执行一次。

3.1.4、AtomicReference

AtomicReference和 AtomicInteger非常类似,不同之处就在于 AtomicInteger是对整数的封装,底层采用的是 compareAndSwapInt实现CAS,比较的是数值是否相等,而 AtomicReference则对应普通的对象引用,底层使用的是 compareAndSwapObject实现CAS,比较的是两个对象的地址是否相等。也就是它可以保证你在修改对象引用时的线程安全性。

多个线程之间的操作无论采用何种执行时序或交替方式,都要保证不变性条件不被破坏,要保持状态的一致性,就需要在单个原子操作中更新相关的状态变量。
 

分析: 如果你的日志中搜不到上面信息,说明你的注解处理器没有被添加到javac的 classpath 中。一般问题就是你的META-INF/services/javax.annotation.processing.Processor声明有问题,javac无法找到你的注解处理器。有些同学可能是通过 google 的 AutoService 来生成META-INF/services/javax.annotation.processing.Processor的,这种情况下也要自己检查是否 OK(譬如之前安卓中 AGP 有一段时间的中间过渡版本就修改了 classpath,需要手动将 compile 改成 annotationProcessor 才行)。

2.在你的日志中搜索Round关键字,建议直接搜Round 1:这样的格式容易点,看到的日志会是如下。
 

添加上面参数后一定要将你的构建日志追加到一个磁盘文件中,因为日志会变得非常庞大,同时也变得很容易定位问题。

通过构建日志分析定位问题

执行你的构建任务,完毕后分析定位主要分为如下几个步骤,每一步都是一种场景的定位,循序渐进定位分析即可。

1.在你的日志中搜索你的 Processor 类名,譬如TestAnnotationProcessor.class,看到的日志会是如下。
 

我们可以看到 getAndAddInt(Objectvar1,longvar2,intvar4),传进来的第一个参数是当前的一个对象,也就是我们的:count.incrementAndGet(),在 getAndAddInt()中,var1就是count,var2就是当前的值,比如当前循环中count值为 2,var4为每次递增1

其次 getAndAddInt()方法中涉及到的两个方法调用都定义为native,即java底层实现的本地方法

  • getIntVolatile():获取保存当前对象count的主存地址的引用(注意不是对象的值,是引用)。
  • compareAndSwapInt():比较当前对象的值和底层该对象的值是否相等,如果相等,则将当前对象值加1,如果不相等,则重新去获取底层该对象的值,这个方法的实现就是CPU的CAS(compare and swap)操作。

我们知道 volatile具有一致性的特征,但是它不具备原子性,为什么 AtomicInteger却同时具备一致性和原子性,原来在 AtomicInteger源码中实现了这样一串代码:privatevolatileintvalue;,在 AtomicInteger内部实现就使用了 volatile关键字,这就是为什么执行CAS(对CAS有疑问的点击此处)操作的时候,从底层获取的数据就是最新的数据:

  • 如果当前要保存的值和内存中最新的值不相等的话,说明在这个过程中被其他线程修改了,只能获取更新当前值为最新值,再那这个当前值再去和重新去内存获取的最新值比较,直到二者相等的时候,才完成+1的过程.

使用 AtomicInteger的好处在于,它不同于 sychronized关键字或 lock用锁的形式来实现原子性,加锁会影响性能,而是采用循环比较的形式来提高性能。

3.1.2、AtomicLong

AtomicLong 是作用是对长整形进行原子操作,依靠底层的cas来保障原子性的更新数据,在要添加或者减少的时候,会使用死循环不断地cas到特定的值,从而达到更新数据的目的。

(编辑:惠州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读