原子性
原子性,不可分割,操作不能打断.比如人说一句话不被打断这就是原子性.程序也是执行某个操作被打断就会产生致命的错误.
原子性反面案例
class Data{
volatile int number=0;
public void numberIncrement(){
this.number++;
}
}
public class Main {
public static void main(String[] args) {
Data data = new Data();
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
data.numberIncrement();
}
},"t"+i).start();
}
while (Thread.activeCount() > 2){
Thread.yield();
}
System.out.println(data.number);
}
}
这个程序目的是10个线程把number变为10000,因为volatile不保证原子性,所以是达不到效果的.输出结果如下
保证原子性案例
class Data{
AtomicInteger atomicInteger = new AtomicInteger();
volatile int number=0;
public void numberIncrement(){
this.number++;
}
public void atomicIntegerIncrement(){
this.atomicInteger.incrementAndGet();
}
}
public class Main {
public static void main(String[] args) {
Data data = new Data();
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
data.numberIncrement();
data.atomicIntegerIncrement();
}
},"t"+i).start();
}
while (Thread.activeCount() > 2){
Thread.yield();
}
System.out.println("volatile修饰的int type:"+data.number);
System.out.println("原子类:"+data.atomicInteger);
}
}
如上程序输出结果如下,为了看到效果做出了对比
总结
可能有人会说synchronized能保证原子性,我觉得没必要,原子类更加合适这种场景.
原子类的底层原理是CAS+自旋锁实现的,至于CAS具体是什么,后续在研究吧