原子性操作,在多线程下 该变量的操作是原子性的,不需要添加:synchronized
例子
启用100个线程,每个线程做+1的操作,最终的结果应该会得到 100才对
public static void main(String args[]) throws InterruptedException {
//使用线程池
ExecutorService service = Executors.newCachedThreadPool();
TestCount testCount=new TestCount();
long time=System.currentTimeMillis();
//100个线程对count+1
for(int i=1;i<=100;i++){
service.execute(()->testCount.increase());
}
// 等待上述的线程执行完
service.shutdown();
service.awaitTermination(1, TimeUnit.DAYS);
System.out.println("计算结果:"+testCount.getCount());
}
//类
public static final class TestCount{
private Integer count=0;
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public void increase(){
count++;
}
}
最终的记结果会出现 97 96 .等的情况,就是说count 这个共享变量是线程不安全的呀,线程都共享这个变量
image.png
使用 AtomicInteger 修改count 变量
public static final class TestCount{
private AtomicInteger count = new AtomicInteger(0);
public Integer getCount() {
return count.get();
}
public void increase(){
count.incrementAndGet();
}
}
不管执行多少次都是100 结果正确
image.png
Atomic 的类
image.png基本类型:
AtomicBoolean:布尔型
AtomicInteger:整型
AtomicLong:长整型
数组:
AtomicIntegerArray:数组里的整型
AtomicLongArray:数组里的长整型
AtomicReferenceArray:数组里的引用类型
引用类型:
AtomicReference:引用类型
AtomicStampedReference:带有版本号的引用类型
AtomicMarkableReference:带有标记位的引用类型
对象的属性:
AtomicIntegerFieldUpdater:对象的属性是整型
AtomicLongFieldUpdater:对象的属性是长整型
AtomicReferenceFieldUpdater:对象的属性是引用类型
JDK8新增DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder
是对AtomicLong等类的改进。比如LongAccumulator与LongAdder在高并发环境下比AtomicLong更高效。
AtomicReferenceFieldUpdater、AtomicIntegerFieldUpdater和AtomicLongFieldUpdater是基于反射的实用工具,可以提供对关联字段类型的访问。例如AtomicIntegerFieldUpdater可以对指定类的指定volatile int字段进行原子更新。
原子类可以替换锁吗?
原子类不是锁的常规替换方法。仅当对象的重要更新限定于单个变量时才应用它。
原子类和java.lang.Integer等类的区别
原子类不提供诸如hashCode和compareTo之类的方法。因为原子变量是可变的。
:LongAdder中会维护一组(一个或多个)变量,这些变量加起来就是要以原子方式更新的long型变量。当更新方法add(long)在线程间竞争时,该组变量可以动态增长以减缓竞争。方法sum()返回当前在维持总和的变量上的总和。与AtomicLong相比,LongAdder更多地用于收集统计数据,而不是细粒度的同步控制。在低并发环境下,两者性能很相似。但在高并发环境下,LongAdder有着明显更高的吞吐量,但是有着更高的空间复杂度。
import java.util.concurrent.atomic.AtomicLong;
class Counter {
private static AtomicLong counter = new AtomicLong(0);
public static long addOne() {
return counter.incrementAndGet();
}
}
网友评论