java并发库提供了很多原子类来支持并发访问的数据安全性,除了常用的

  1. AtomicIntegerAtomicBooleanAtomicLong 外还有
  1. AtomicReference 用以支持对象的原子操作:AtomicReference<V> 可以封装引用一个V实例,
  2. 通过
  1. public final boolean compareAndSet(V expect, V update)
  1. 可以支持并发访问,set的时候进行对比判断,如果当前值和操作之前一样则返回false,否则表示数据没有 变化,例如下面的代码
    使用 AtomicReference 实现了并发计数:
  1. package test;
  2.  
  3. import java.util.concurrent.CountDownLatch;
  4. import java.util.concurrent.atomic.AtomicReference;
  5.  
  6. public class TS {
  7. public static void main(String[] args) throws InterruptedException {
  8. dfasd111();
  9. }
  10.  
  11. private static AtomicReference<Integer> ar = new AtomicReference<Integer>();
  12.  
  13. public static void dfasd111() throws InterruptedException {
  14. int t = ;
  15. final int c = ;
  16. final CountDownLatch latch = new CountDownLatch(t);
  17. for (int i = ; i < t; i++) {
  18. new Thread(new Runnable() {
  19. @Override
  20. public void run() {
  21. for (int i = ; i < c; i++) {
  22. while (true) {
  23. Integer temp = ar.get();
  24. if (ar.compareAndSet(temp, temp + )) {
  25. break;
  26. }
  27. }
  28. }
  29. latch.countDown();
  30. }
  31. }).start();
  32. }
  33. latch.await();
  34. System.out.println(ar.get()); //
  35. }
  36.  
  37. public final void test() {
  38. System.out.println(this.getClass());
  39. }
  40. }
  1. 一、原子量实现的计数器
  1. import java.util.HashSet;
  2. import java.util.Set;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5. import java.util.concurrent.atomic.AtomicInteger;
  6. public class AtomicCounter {
  7.  
  8. private AtomicInteger value = new AtomicInteger();
  9.  
  10. public int getValue() {
  11. return value.get();
  12. }
  13.  
  14. public int increase() {
  15. return value.incrementAndGet();// 内部使用死循环for(;;)调用compareAndSet(current, next)
  16. // return value.getAndIncrement();
  17. }
  18.  
  19. public int increase(int i) {
  20. return value.addAndGet(i);// 内部使用死循环for(;;)调用compareAndSet(current, next)
  21. // return value.getAndAdd(i);
  22. }
  23.  
  24. public int decrease() {
  25. return value.decrementAndGet();// 内部使用死循环for(;;)调用compareAndSet(current, next)
  26. // return value.getAndDecrement();
  27. }
  28.  
  29. public int decrease(int i) {
  30. return value.addAndGet(-i);// 内部使用死循环for(;;)调用compareAndSet(current, next)
  31. // return value.addAndGet(-i);
  32. }
  33.  
  34. public static void main(String[] args) {
  35. final AtomicCounter counter = new AtomicCounter();
  36. ExecutorService service = Executors.newCachedThreadPool();
  37. for (int i = ; i < ; i++) {
  38. service.execute(new Runnable() {
  39. @Override
  40. public void run() {
  41. System.out.println(counter.increase());
  42. }
  43. });
  44. }
  45. service.shutdown();
  46. }
  47. }

二、原子量实现的银行取款

  1. import java.util.Random;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.atomic.AtomicLong;
  5. public class Account {
  6.  
  7. private AtomicLong balance;
  8.  
  9. public Account(long money) {
  10. balance = new AtomicLong(money);
  11. System.out.println("Total Money:" + balance);
  12. }
  13.  
  14. public void deposit(long money) {
  15. balance.addAndGet(money);
  16. }
  17.  
  18. public void withdraw(long money) {
  19. for (; ; ) {//保证即时同一时间有人也在取款也可以再次尝试取款,如果不需要并发尝试取款,可以去掉这句
  20. long oldValue = balance.get();
  21. if (oldValue < money) {
  22. System.out.println(Thread.currentThread().getName() + " 余额不足! 余额:" + balance);
  23. break;
  24. }
  25. try {Thread.sleep(new Random().nextInt());} catch (Exception e) { }// 模拟取款时间
  26. if (balance.compareAndSet(oldValue, oldValue - money)) {
  27. System.out.println(Thread.currentThread().getName() + " 取款 " + money + " 成功! 余额:" + balance);
  28. break;
  29. }
  30. System.out.println(Thread.currentThread().getName() + " 遇到并发,再次尝试取款!");
  31. }
  32. }
  33.  
  34. public static void main(String[] args) {
  35. final Account account = new Account();
  36. ExecutorService pool = Executors.newCachedThreadPool();
  37. int i = ;
  38. while (i++ < ) {
  39. pool.execute(new Runnable() {
  40. @Override
  41. public void run() {
  42. account.withdraw();
  43. }
  44. });
  45. }
  46. pool.shutdown();
  47. }
  48. }
  1.  

java 原子量Atomic举例(AtomicReference)的更多相关文章

  1. Java线程--Atomic原子类使用

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871241.html Java线程--Atomic原子类使用 package concurr ...

  2. Java中Atomic包的实现原理及应用

    1. 同步问题的提出 假设我们使用一个双核处理器执行A和B两个线程,核1执行A线程,而核2执行B线程,这两个线程现在都要对名为obj的对象的成员变量i进行加1操作,假设i的初始值为0,理论上两个线程运 ...

  3. java线程:Atomic(原子的)

    一.何谓Atomic? Atomic一词跟原子有点关系,后者曾被人认为是最小物质的单位.计算机中的Atomic是指不能分割成若干部分的意思.如果一段代码被认为是Atomic,则表示这段代码在执行过程中 ...

  4. 24.Java中atomic包中的原子操作类总结

    1. 原子操作类介绍 在并发编程中很容易出现并发安全的问题,有一个很简单的例子就是多线程更新变量i=1,比如多个线程执行i++操作,就有可能获取不到正确的值,而这个问题,最常用的方法是通过Synchr ...

  5. java线程:Atomic(原子)

    .何谓Atomic? Atomic一词跟原子有点关系,后者曾被人认为是最小物质的单位.计算机中的Atomic是指不能分割成若干部分的意思.如果一段代码被认为是Atomic,则表示这段代码在执行过程中, ...

  6. java内存配置举例

    常见配置举例  堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~ ...

  7. java基础-泛型举例详解

    泛型 泛型是JDK5.0增加的新特性,泛型的本质是参数化类型,即所操作的数据类型被指定为一个参数.这种类型参数可以在类.接口.和方法的创建中,分别被称为泛型类.泛型接口.泛型方法. 一.认识泛型 在没 ...

  8. Hbase关于Java常用API举例

    1. HBase相关对Admin操作的的API封装在HBaseAdmin中,封装了HBase常用操作的API 使用方法: pom.xml <!-- https://mvnrepository.c ...

  9. java常见数据结构举例

    1. ArrayList(参考) import java.util.*; public class Test{ public static void main(String [] args){ Arr ...

随机推荐

  1. 找不到或无法载入主类 org.jivesoftware.openfire.starter.ServerStarter

    刚接触openfire的配置就出现了这个错误.解决方法非常easy,忘记了将openfire的源文件加入到user entries中了

  2. CF #261 div2 D. Pashmak and Parmida&#39;s problem (树状数组版)

    Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants he ...

  3. 《ASP.NET》数据绑定—DropDownList、ListBox

    DropDownList和ListBox实现两级联动功能.他们也能够将从后台数据库中搜选的出来的信息加以绑定.这里要实现的功能是在DropDownList中选择"省",然后让Lis ...

  4. kindle paperwhite 简单笔记按名称分类

    已更新python,见新博客  http://www.hrwhisper.me/archives/708 写作背景: 南京决赛比赛完那天晚上写的. 使用方法: 将My Clippings.txt 放在 ...

  5. query中prop()方法和attr()方法的区别

    query1.6中新加了一个方法prop(),一直没用过它,官方解释只有一句话:获取在匹配的元素集中的第一个元素的属性值. 官方例举的例子感觉和attr()差不多,也不知道有什么区别,既然有了prop ...

  6. java set转list,数组与list的转换

    读zookeeper的源码(zookeeper.java)时发现的,平时没有怎么注意: private final ZKWatchManager watchManager; List<Strin ...

  7. ES6的基础知识总结

    一. ES6 ES6中定义变量使用 let/const let 使用let定义的变量不能进行"变量提升" 同一个作用域中,let不能重复定义相同的变量名 使用var在全局作用域中定 ...

  8. 常用协议(SPI, UART, I2C)

    SPI: SPI是全双工的同步串行接口,数据速率可达几Mbps,在一般应用中有4根信号线:MOSI, MISO, SCK, SS. 根据时钟极性(CPOL)及相位(CPHA)不同可以组合成4种工作模式 ...

  9. SPRINGAOP实现基于注解的数据源动态切换(转)

    需求 代码实现读写数据库分离 武器 spring3.0以上版本 实现思路 1.继承org.springframework.jdbc.datasource.lookup.AbstractRoutingD ...

  10. 算法学习笔记(六) 二叉树和图遍历—深搜 DFS 与广搜 BFS

    图的深搜与广搜 复习下二叉树.图的深搜与广搜. 从图的遍历说起.图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其 ...