Java中volatile和AtomicLong的区别与原理
【摘要】 随着多线程编程的普及,volatile和AtomicLong这两个关键字被越来越多的使用。但是很多人并不理解它们的原理以及区别。今天我就来通过一个典型的场景,讲解 volatile 和 AtomicLong 的用法、原理以及区别,希望可以帮助大家更好地使用这两者。我们假设有这样一个多线程场景:存在一个长整型变量,多个线程同时进行读写操作。为了保证线程安全,我们通常会进行同步,但是同步操作又会...
随着多线程编程的普及,volatile和AtomicLong这两个关键字被越来越多的使用。但是很多人并不理解它们的原理以及区别。今天我就来通过一个典型的场景,讲解 volatile 和 AtomicLong 的用法、原理以及区别,希望可以帮助大家更好地使用这两者。我们假设有这样一个多线程场景:存在一个长整型变量,多个线程同时进行读写操作。为了保证线程安全,我们通常会进行同步,但是同步操作又会影响效率。这个时候我们就可以考虑用 volatile 或者 AtomicLong 来优化。先说说 volatile,它可以保证变量的可见性,具体来说就是当一个线程修改了 volatile 变量,新值对其他线程立即可见。这是因为volatile变量直接操作主内存,而不是线程的工作内存。
java
public class VolatileExample {
volatile long count = 0;
public void increment() {
count++;
}
public long getCount() {
return count;
}
}
这里通过 volatile 关键字,可以保证多个线程都能读取到 count 的最新的值。但是,volatile 并不能保证原子性。什么意思呢?我们来看看下面的代码:
java
public void increment() {
count++;
}
// 这里的递增操作并不是原子的,实际会分为三步
// 1. 读取count值
// 2. 计算值+1
// 3. 写入新的值
也就是说某一个时刻,可能有两个线程同时读取了 count 值,然后分别增加,这就破坏了原子性。要解决这个问题,我们就需要 AtomicLong 了。AtomicLong 通过 CAS (Compare And Swap) 算法实现了对长整型的原子操作。看一个例子:
java
AtomicLong atomicCount = new AtomicLong();
public void increment() {
atomicCount.getAndIncrement();
}
getAndIncrement()会先获取当前的值,然后原子地增加,最后返回旧值。这样多个线程调用的时候可以保证原子性。AtomicLong 的 CAS 原理是通过循环调用 CAS 指令,直到更新成功为止:
java
do {
// 获取旧的预期值
oldValue = atomicCount.get();
// 用CAS指令更新值,如果预期值一样才更新
success = compareAndSet(oldValue, oldValue + 1);
// 如果失败,继续循环执行CAS
} while(!success);
通过 CAS 不断尝试更新,直到成功为止。所以,总结一下 volatile 和 AtomicLong 的区别:1. volatile 保证可见性,AtomicLong 保证原子性
2. volatile 不会对代码产生线程锁,AtomicLong 会通过 CAS 产生线程开销
3. volatile 是通过直接操作主内存实现,AtomicLong 是通过 CAS 实现那么什么时候该用 volatile,什么时候该用 AtomicLong 呢?如果只要保证可见性,那用 volatile 即可。如果需要原子操作,如对数字进行递增操作,这时就需要用 AtomicLong。当然,synchronized和Lock也能保证原子性,但是通过 CAS 实现的 AtomicLong 性能会更好一些。以上就是本文的全部内容了,通过一个典型多线程场景讲解了 volatile 和 AtomicLong 的用法、原理以及区别。这两个关键字非常有用,正确理解后可以充分利用它们带来的优势
2. volatile 不会对代码产生线程锁,AtomicLong 会通过 CAS 产生线程开销
3. volatile 是通过直接操作主内存实现,AtomicLong 是通过 CAS 实现那么什么时候该用 volatile,什么时候该用 AtomicLong 呢?如果只要保证可见性,那用 volatile 即可。如果需要原子操作,如对数字进行递增操作,这时就需要用 AtomicLong。当然,synchronized和Lock也能保证原子性,但是通过 CAS 实现的 AtomicLong 性能会更好一些。以上就是本文的全部内容了,通过一个典型多线程场景讲解了 volatile 和 AtomicLong 的用法、原理以及区别。这两个关键字非常有用,正确理解后可以充分利用它们带来的优势
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)