java并发编程实战第六章(8)使用原子变量
2015-09-05 08:26
441 查看
7.使用原子变量
说明:原子变量(Atomic Variable): 提供了单个变量上的原子操作。在编译程序时,
java代码中的每个变量,每个操作都将被转换成机器可以理解的指令。
例如,当给一个变量赋值时,在java代码中只使用一个指令,
但是编译这个程序时,指令被转换成JVM语言的不同指令。
当多个线程共享同一个变量时,就会发生数据不一致的错误,java中引入原子变量来避免该类错误。
当一个线程在堆原子变量操作时,如果其他线程也试图对同一原子变量执行操作,
原子变量提供了一套机制来检查操作是否在一步之内完成。
这种操作就是CAS原子操作(Compare And Set).就是说先获取变量的值,
然后在本地改变变量的值,然后试图用这个改变的值去替换之前的值,
如果之前的 值没有被其他线程改变就可以执行这个操作,否则,方法将再执行这个操作。
。
原子变量不使用锁或者其他同步机制来保护对其值的并发访问。所有操作都是基于CAS原子操作的。
它保证了多线程在同一时间操作一个原子变量而不会产生数据不一致的错误,性能优于使用同步
机制保护的普通变量。但是这种机制会引起ABA问题,
本范例使用AtomicLong类
java还提供了其他原子类:AtomicBoolean
AtomicInteger 和AtomicReference是原子类的其他实现类。
本案例继续模拟银行操作,由于本书中有众多实际生活中的案例,生产者消费者模型,银行ATM存取款模型,在第7章结束后关于本书的内容会继续总结下去。敬请期待。。。
实例代码:
说明:原子变量(Atomic Variable): 提供了单个变量上的原子操作。在编译程序时,
java代码中的每个变量,每个操作都将被转换成机器可以理解的指令。
例如,当给一个变量赋值时,在java代码中只使用一个指令,
但是编译这个程序时,指令被转换成JVM语言的不同指令。
当多个线程共享同一个变量时,就会发生数据不一致的错误,java中引入原子变量来避免该类错误。
当一个线程在堆原子变量操作时,如果其他线程也试图对同一原子变量执行操作,
原子变量提供了一套机制来检查操作是否在一步之内完成。
这种操作就是CAS原子操作(Compare And Set).就是说先获取变量的值,
然后在本地改变变量的值,然后试图用这个改变的值去替换之前的值,
如果之前的 值没有被其他线程改变就可以执行这个操作,否则,方法将再执行这个操作。
。
原子变量不使用锁或者其他同步机制来保护对其值的并发访问。所有操作都是基于CAS原子操作的。
它保证了多线程在同一时间操作一个原子变量而不会产生数据不一致的错误,性能优于使用同步
机制保护的普通变量。但是这种机制会引起ABA问题,
本范例使用AtomicLong类
java还提供了其他原子类:AtomicBoolean
AtomicInteger 和AtomicReference是原子类的其他实现类。
本案例继续模拟银行操作,由于本书中有众多实际生活中的案例,生产者消费者模型,银行ATM存取款模型,在第7章结束后关于本书的内容会继续总结下去。敬请期待。。。
实例代码:
[code]/** * * @author fcs * @date 2015-6-22 * 描述:使用原子变量 * 说明:使用原子变量模拟银行存取款模型 */ public class Acount { private AtomicLong balence; public Acount() { balence = new AtomicLong(); } public AtomicLong getBalence() { return balence; } public void setBalence(AtomicLong balence) { this.balence = balence; } //增加balence存款 public void addBalence(long amount){ this.balence.getAndAdd(amount); } //减少balence存款 public void subBalence(long amount){ this.balence.getAndAdd(- amount); } }
[code]/** * * @author fcs * @date 2015-6-22 * 描述:模拟从账户取款 * 说明: */ public class Bank implements Runnable{ private Acount acount ; public Bank(Acount acount) { this.acount = acount; } @Override public void run() { for(int i =0 ;i< 1000000;i++){ acount.addBalence(1000); } } }
[code]/** * * @author fcs * @date 2015-6-22 * 描述:模拟公司存款 * 说明: */ public class Company implements Runnable { private Acount acount; public Company(Acount acount) { this.acount = acount; } @Override public void run() { for(int i =0;i< 1000000;i++){ acount.subBalence(1000); try { TimeUnit.MILLISECONDS.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
相关文章推荐
- SpringMVC环境配置
- ACM中java的使用 (转)
- 一个项目思路(1):用反射机制写的函数,使2个javabean相同属性一次性导入
- 【小熊刷题】power of two, pow(x, n) <Leetcode 231, 50 Java>
- Java堆.栈和常量池 笔记
- Java设计模式 之 代理模式
- Java多线程(1)
- Action参数缓存-Spring单例
- Java使用Calendar类在控制台输出指定年份和月份的日历
- JAVA注释
- java将float字符串还原为float数字
- Java Spring AOP用法
- Injecting Spring Beans into Java Servlets
- Java之工具-------Junit自己的测试工具MyJUnit
- Java虚拟机内存模型
- Atitit. 衡量项目规模 ----包含的类的数量 .net java类库包含多少类 多少个api方法??
- Atitit. 衡量项目规模 ----包含的类的数量 .net java类库包含多少类 多少个api方法??
- Atitit. 衡量项目规模 ----包含的类的数量 .net java类库包含多少类 多少个api方法??
- java安全沙箱(四)之安全管理器及Java API
- Java 8函数式编程学习笔记