Java volatile int比AtomicInteger快吗
我正在做一个示例练习,我发现一个奇怪的观察结果,如果我用volatile替换AutomicInteger,程序运行速度会更快。注意:我只做读取操作 代码:Java volatile int比AtomicInteger快吗,java,Java,我正在做一个示例练习,我发现一个奇怪的观察结果,如果我用volatile替换AutomicInteger,程序运行速度会更快。注意:我只做读取操作 代码: import java.util.ArrayList; 导入java.util.List; 导入java.util.concurrent.AtomicInteger; 公共班机{ AtomicInteger=新的AtomicInteger(100000000); //易失整数=100000000; 公共静态void main(字符串[]arg
import java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.AtomicInteger;
公共班机{
AtomicInteger=新的AtomicInteger(100000000);
//易失整数=100000000;
公共静态void main(字符串[]args){
//我们将存储线程,以便检查它们是否完成
List threads=new ArrayList();
长启动=System.currentTimeMillis();
Main Main=新Main();
//我们将创建500个线程
对于(int i=0;i<500;i++){
Runnable task=newmyrunnable(main.integer);
线程工作者=新线程(任务);
//我们可以设置线程的名称
worker.setName(String.valueOf(i));
//启动线程,不要直接调用run()方法
worker.start();
//记住线程以便以后使用
线程。添加(worker);
}
int运行=0;
做{
运行=0;
用于(线程:线程){
if(thread.isAlive()){
运行++;
}
}
System.out.println(“我们有“+running+”running threads.”);
}同时(运行>0);
System.out.println(“所需总时间:”+(System.currentTimeMillis()-start));
}
}
MyRunnable类:
import java.util.concurrent.atomic.AtomicInteger;
public class MyRunnable implements Runnable {
private final AtomicInteger countUntil;
MyRunnable(AtomicInteger countUntil) {
this.countUntil = countUntil;
}
@Override
public void run() {
long sum = 0;
for (long i = 1; i < countUntil.intValue(); i++) {
sum += i;
}
System.out.println(sum);
}
}
导入java.util.concurrent.AtomicInteger;
公共类MyRunnable实现Runnable{
私有最终原子整数countUntil;
MyRunnable(原子整数countUntil){
this.countUntil=countUntil;
}
@凌驾
公开募捐{
长和=0;
for(长i=1;i
在我的计算机上使用AutomicInteger运行此程序所需的时间
所需总时间:102169
所需总时间:90375
在我的计算机上使用volatile运行此程序所需的时间
所需总时间:66760
所需总时间:71773
这是否意味着volatile在读取操作方面也比AutomicInteger快?这个问题取决于特定的JVM、硬件和操作系统,因此唯一可能的答案是“可能”。在读取上下文中,AtomicInteger基本上是围绕着
volatile int
的薄型包装器:
private volatile int value;
public final int get() {
return value;
}
public int intValue() {
return get();
}
不要期望包装比单独使用包装值更快。如果JVM使用内联,它的速度只能与volatile int
一样快
提示:如果您“只执行读取操作”,则速度会更快:
static final int integer= 100000000;
如果很少有应用程序注意到这一点,那么volatile int可能比AtomicInteger更快。不过,AtomicInteger提供了更广泛的潜在用途 volatile int比AtomicInteger快吗 原子的访问和更新的内存效应通常遵循挥发物的规则,如Java中所述™ 语言规范。以下是volatile int与原子类型的比较
- get具有读取易失性变量的记忆效果
- set具有写入(赋值)易失性变量的记忆效果
- lazySet具有写入(分配)易失性变量的内存效应,但它允许使用后续(但不是以前)内存操作进行重新排序,这些操作本身不会对普通非易失性写入施加重新排序约束。在其他使用上下文中,lazySet可能在为垃圾收集而清空一个永远不会被访问的引用时应用
- weakCompareAndSet以原子方式读取和有条件地写入变量,但不会在排序之前创建任何事件,因此对于除weakCompareAndSet目标之外的任何变量的先前或后续读取和写入均不提供任何保证
- compareAndSet和所有其他读取和更新操作(如Get和Increment)都具有读取和写入易失性变量的内存效应
AtomicInteger
的存在使得对整数执行复合原子操作变得很容易,例如addAndGet
,getAndAdd
,getAndSet
,等等。如果您不需要这些操作,那么您应该坚持使用volatile int
,因为正如托马斯兹·努尔基维茨在他的回答中所解释的那样,原子整数
是在volatile int
之上实现的。我创建了自定义包装器来验证,是的,这就是原因。@AmitDeshpande:所以您得到的计时与原子整数
?你能分享你的microbenchmark结果吗?第一次运行1:所需总时间:93059第二次运行:所需总时间:80608
static final int integer= 100000000;