首页 > 代码库 > 原子变量与CAS算法
原子变量与CAS算法
上一节讨论了 volatile关键字,volatile关键字修饰的作用是不具有 "原子性" 和 "互斥性的"
例如 i++ 操作 就不是一个原子性的操作,i++ 其实分为3个步骤进行 "读-改-写"
int temp = i;
i = i + 1;
i= temp;
先看一段代码:
package com.java.juc; public class TestAtomicDemo { public static void main(String[] args) { AtomicDemo ad = new AtomicDemo(); for(int i = 0;i<10;i++){ new Thread(ad).start(); } } } class AtomicDemo implements Runnable{ private int seriesNumber = 0; public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getSeriesNumber()); } public int getSeriesNumber() { return seriesNumber++; } }
创建10个线程,每个线程对变量进行+1操作,
运行结果会出现如下等问题:
0
5
4
3
2
1
0
6
7
8
出现这种情况的主要原因就是 i++不是一个 原子性 操作
解决此问题的方法可以使用 原子变量
原子变量:jdk1.5以后 java.util.concurrent.atomic包下提供了常用的原子变量。
原子变量底层主要是有两个作用:
1.volatile 保证内存可见性
2.CAS(compare-And-Swap)保证数据的原子性
CAS 算法是硬件对于并发操作共享数据的支持
CAS 包含了三个操作数:
内存值 V
预估值 A
更新值 B
当且仅当 V== A 时,V = B. 否则将不做任何操作。
使用原子变量比锁的效率要高很多,使用锁时等待的线程会进入阻塞,使用Atomic进行等待的线程并不会进入阻塞状态,还是持有cpu资源,只是不断询问是否该轮到他执行了。
使用 原子变量进行改写
package com.java.juc; import java.util.concurrent.atomic.AtomicInteger; public class TestAtomicDemo { public static void main(String[] args) { AtomicDemo ad = new AtomicDemo(); for(int i = 0;i<10;i++){ new Thread(ad).start(); } } } class AtomicDemo implements Runnable{ // private int seriesNumber = 0; private AtomicInteger seriesNumber = new AtomicInteger(); public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getSeriesNumber()); } public int getSeriesNumber() { return seriesNumber.getAndIncrement(); } }
原子变量与CAS算法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。