- java.util.concurrent.atomic
-
A small toolkit of classes that support lock-free thread-safe programming on single variables.
- 原子操作类,赋值操作要么成功,要么失败,没有中间态(无锁线程安全
public void testAtomic() {
//use Unsafe.compareAndSwapInt for updates
AtomicInteger atomicInteger = new AtomicInteger();
//自增1,并获取原来的值
int oldValue = atomicInteger.getAndIncrement();
AtomicLong atomicLong = new AtomicLong();
//可以对数组中每个元素原子性的修改
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);
//use Unsafe.compareAndSwapInt for updates(1 true,0 false)
AtomicBoolean atomicBoolean = new AtomicBoolean();
//可以原子更新的对象引用
AtomicReference<Object> atomicReference = new AtomicReference<>();
}
- Unsafe.class 中getAndAddInt方法
- compareAndSwapInt 修改成功时返回true,修改失败时返回false
// C:\Program Files\Java\jdk1.8.0_221\jre\lib\rt.jar!\sun\misc\Unsafe.class
//var1--AtomicInteger实例对象
//var2--valueOffset AtomicInteger类中value字段属性的地址偏移量
//var4--value值需要增加、减少的值(自增为+1,自减为-1)
//Unsafe.class
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
//var5 期望值,修改之前的值
var5 = this.getIntVolatile(var1, var2);
//var5 期望值(当前值),var5 + var4 更新(后)值
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
-
Atomic classes are designed primarily as building blocks for implementing non-blocking data structures and related infrastructure classes. The compareAndSet method is not a general replacement for locking. It applies only when critical updates for an object are confined to a single variable.
- LongAdder 多线程统计求和
-
当多个线程更新用于诸如收集统计信息而不是用于细粒度的同步控制之类的公共和时,此类通常比AtomicLong更可取。在低更新争用下,两个类具有相似的特征。但是在竞争激烈的情况下,此类的预期吞吐量会大大提高,但要消耗更多的空间。
public void testAdder() throws InterruptedException {
AtomicLong atomicLong = new AtomicLong();
//多个线程求和操作 更高性能
LongAdder longAdder=new LongAdder();
Thread[] threads = new Thread[1000];
for (int i = 0; i < 1000; i++) {
Thread thread = new Thread(() -> {
for (int j = 0; j < 100000; j++) {
// atomicLong.getAndIncrement();
longAdder.increment();
}
});
threads[i] = thread;
}
long l1 = System.currentTimeMillis();
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
long l2 = System.currentTimeMillis();
// long sum = atomicLong.get();
long sum = longAdder.sum();
System.out.println("sum = " + sum);
System.out.println("l2-l1 = " + (l2 - l1));
}