JUC:原子操作类
4.7 原子操作类
4.7.1 基本类型原子类
- AtomicInteger
- AtomicBoolean
- AtomicLong
常用API:
- get()
- getAndSet(int newValue)
- getAndIncrement();
- getAndDecrement();
- getAndAdd(int delta)
- compareAndSet(int expect, int newValue);
4.7.2 数组类型原子类
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
常用API
- get(int index)
- getAndSet(int index, int newValue)
4.7.3 引用类型原子类
- AtomicReference
- AtomicStampedReference: 带版本号:+1
- AtomicMarkableReference:带标识:是否被修改过:false -> true。一次性数据
4.7.4 对象的属性修改原子类
-
AtomicIntegerFieldUpdater
-
AtomicLongFieldUpdater
-
AtomicReferenceFieldUpdater
-
使用目的:以一种线程安全的方式修改非线程安全对象内的某些字段
-
使用要求:
- 更新的属性必须使用public volatile修饰
- 对象的属性修改原子类都是抽象类,使用时必须使用静态方法newUpdater()创建一个更新器
public class AtomicTest {
public static void main(String[] args) {
Student tom = new Student("Tom", 23);
System.out.println(tom);
AtomicIntegerFieldUpdater<Student> updater = AtomicIntegerFieldUpdater.newUpdater(Student.class, "age"); // 使用静态方法创建
updater.compareAndSet(tom, 23, 18);
System.out.println(tom);
}
}
@Data
@AllArgsConstructor
class Student{
private String name;
public volatile int age; // 使用public volatile 修饰
}
4.7.5 原子操作增强类原理深度解析
- DoubleAccumulator
- DoubleAdder
- LongAccumulator
- LongAdder : 如果是Java8,推荐使用LongAdder,比AtomicLong性能高(减少乐观锁重试次数)
点赞计数器:看看性能
public class AtomicTest {
public static void main(String[] args) throws InterruptedException {
int _1W = 100000;
int threadNum = 50;
CountDownLatch countDownLatch1 = new CountDownLatch(threadNum);
CountDownLatch countDownLatch2 = new CountDownLatch(threadNum);
CountDownLatch countDownLatch3 = new CountDownLatch(threadNum);
ClickNumber clickNumber = new ClickNumber();
long start = System.currentTimeMillis();
for(int i = 0; i < threadNum; i++) {
new Thread(()->{
try{
for(int j = 0; j < _1W * 100; j++) {
clickNumber.clickByLongAdder();
}
}finally {
countDownLatch1.countDown();
}
}).start();
}
countDownLatch1.await();
long end = System.currentTimeMillis();
System.out.println( clickNumber.getLongAdder() + "LongAdder Time: " + (end - start));
start = System.currentTimeMillis();
for(int i = 0; i < threadNum; i++) {
new Thread(()->{
try {
for(int j = 0; j < _1W * 100; j++) {
clickNumber.clickByAtomicLong();
}
}finally {
countDownLatch2.countDown();
}
}).start();
}
countDownLatch2.await();
end = System.currentTimeMillis();
System.out.println( clickNumber.getAtomicLong() + "AtomicLong Time: " + (end - start));
start = System.currentTimeMillis();
for(int i = 0; i < threadNum; i++) {
new Thread(()->{
try {
for(int j = 0; j < _1W * 100; j++) {
clickNumber.clickByLongAccumulator();
}
}finally {
countDownLatch3.countDown();
}
}).start();
}
countDownLatch3.await();
end = System.currentTimeMillis();
System.out.println( clickNumber.getLongAccumulator() + "LongAccumulator Time: " + (end - start));
}
}
@Data
class ClickNumber{
AtomicLong atomicLong = new AtomicLong(0);
public void clickByAtomicLong(){
atomicLong.getAndIncrement();
}
LongAdder longAdder = new LongAdder();
public void clickByLongAdder(){
longAdder.increment();
}
LongAccumulator longAccumulator = new LongAccumulator(Long::sum, 0L);
public void clickByLongAccumulator(){
longAccumulator.accumulate(1);
}
}
500000000LongAdder Time: 209
500000000AtomicLong Time: 4241
500000000LongAccumulator Time: 205
Process finished with exit code 0
- 原理分析
base变量: 低并发,直接累加到该变量上Cell[]数组: 高并发,累加进各个线程自己的Cell[i]槽位中- value =
base+sum(Cell[i])
- value =
- 空间换时间,分散热点数据,减少乐观锁的重试次数

浙公网安备 33010602011771号