Atomic翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学
反应中是不可分割的。在我们这里Atomic是指一个操作是不可中断的。即使是在多个线程一起执
行的时候,一个操作一旦开始,就不会被其他线程干扰。
基本类型原子类
-
AtomicInteger
:整型原子类 -
AtomicBoolean
:布尔型原子类 -
AtomicLong
:长整型原子类
基本类型原子类常用API简介
public final int get() //获取当前的值
public final int getAndSet(int newValue)//获取当前的值,并设置新的值
public final int getAndIncrement()//获取当前的值,并自增
public final int getAndDecrement() //获取当前的值,并自减
public final int getAndAdd(int delta) //获取当前的值,并加上预期的值
boolean compareAndSet(int expect, int update) //如果输入的数值等于预期值,则以原子方式将该值设置为输入值(update)
public final void lazySet(int newValue)//最终设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
AtomicInteger案例演示:
package com.nanjing.gulimall.zhouyimo.test;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author zhou
* @version 1.0
* @date 2024/1/14 9:50 下午
*/
public class AtomicIntegerDemo {
public static final int SIZE = 50;
public static void main(String[] args) throws InterruptedException {
MyNumber myNumber = new MyNumber();
for (int i = 1; i <= SIZE; i++) {
new Thread(() -> {
for (int j = 1; j <= 1000; j++) {
myNumber.addPlusPlus();
}
}, String.valueOf(i)).start();
}
System.out.println(Thread.currentThread().getName() + "\t" + "result: " + myNumber.atomicInteger.get());//main result: 49029
}
}
class MyNumber {
AtomicInteger atomicInteger = new AtomicInteger();
public void addPlusPlus() {
atomicInteger.getAndIncrement();
}
}
结果出乎意料,不是50000,说明其他线程没有结束,main线程就打印了
方法一:加时间,等待其他线程执行完,练习可以使用,实际开发不可以用,时间不好确定
方法二:thread.join()等待子线程跑完
package com.nanjing.gulimall.zhouyimo.test;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author zhou
* @version 1.0
* @date 2024/1/14 9:50 下午
*/
public class AtomicIntegerDemo {
public static final int SIZE = 50;
public static void main(String[] args) throws InterruptedException {
MyNumber myNumber = new MyNumber();
Thread[] threads = new Thread[SIZE];
for (int i = 1; i <= SIZE; i++) {
Thread thread = new Thread(() -> {
for (int j = 1; j <= 1000; j++) {
myNumber.addPlusPlus();
}
}, String.valueOf(i));
thread.start();
threads[i - 1] = thread;
}
//等待子线程执行完毕
Arrays.stream(threads).forEach(thread -> {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(Thread.currentThread().getName() + "\t" + "result: " + myNumber.atomicInteger.get());//main result: 50000
}
}
class MyNumber {
AtomicInteger atomicInteger = new AtomicInteger();
public void addPlusPlus() {
atomicInteger.getAndIncrement();
}
}
方法三:CountDownLatch
package com.nanjing.gulimall.zhouyimo.test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author zhou
* @version 1.0
* @date 2024/1/14 9:50 下午
*/
public class AtomicIntegerDemo {
public static final int SIZE = 50;
public static void main(String[] args) throws InterruptedException {
MyNumber myNumber = new MyNumber();
CountDownLatch countDownLatch = new CountDownLatch(SIZE);
for (int i = 1; i <= SIZE; i++) {
new Thread(() -> {
try {
for (int j = 1; j <= 1000; j++) {
myNumber.addPlusPlus();
}
} finally {
countDownLatch.countDown();
}
}, String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "\t" + "result: " + myNumber.atomicInteger.get());//main result: 50000
}
}
class MyNumber {
AtomicInteger atomicInteger = new AtomicInteger();
public void addPlusPlus() {
atomicInteger.getAndIncrement();
}
}
补充阿里巴巴Java手册: