文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习

首先看两段代码,一段是Integer的,一段是AtomicInteger的,为以下:

public class Sample1 {
  private static Integer count = 0;
  synchronized public static void increment() {
    count++;
  }
}

以下是AtomicInteger的:

public class Sample2 {
  private static AtomicInteger count = new AtomicInteger(0);
  public static void increment() {
    count.getAndIncrement();
  }
}

以上两段代码,在使用Integer的时候,必须加上synchronized保证不会出现并发线程同时访问的情况,而在AtomicInteger中却不用加上synchronized,在这里AtomicInteger是提供原子操作的,下面就对这进行相应的介绍。

AtomicInteger介绍

AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。

AtomicInteger使用场景

AtomicInteger提供原子操作来进行Integer的使用,因此十分适合高并发情况下的使用。

AtomicInteger源码部分讲解

public class AtomicInteger extends Number implements java.io.Serializable {
  private static final long serialVersionUID = 6214790243416807050L;
  // setup to use Unsafe.compareAndSwapInt for updates
  private static final Unsafe unsafe = Unsafe.getUnsafe();
  private static final long valueOffset;
  static {
    try {
      valueOffset = unsafe.objectFieldOffset
        (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
  }
  private volatile int value;

以上为AtomicInteger中的部分源码,在这里说下其中的value,这里value使用了volatile关键字,volatile在这里可以做到的作用是使得多个线程可以共享变量,但是问题在于使用volatile将使得VM优化失去作用,导致效率较低,所以要在必要的时候使用,因此AtomicInteger类不要随意使用,要在使用场景下使用。

AtomicInteger实例使用

以下就是在多线程情况下,使用AtomicInteger的一个实例,这段代码是借用IT宅中的一段代码。

 public class AtomicTest {
  static long randomTime() {
    return (long) (Math.random() * 1000);
  }
  public static void main(String[] args) {
    // 阻塞队列,能容纳100个文件
    final BlockingQueue<File> queue = new LinkedBlockingQueue<File>(100);
    // 线程池
    final ExecutorService exec = Executors.newFixedThreadPool(5);
    final File root = new File("D:\\ISO");
    // 完成标志
    final File exitFile = new File("");
    // 原子整型,读个数
    // AtomicInteger可以在并发情况下达到原子化更新,避免使用了synchronized,而且性能非常高。
    final AtomicInteger rc = new AtomicInteger();
    // 原子整型,写个数
    final AtomicInteger wc = new AtomicInteger();
    // 读线程
    Runnable read = new Runnable() {
      public void run() {
        scanFile(root);
        scanFile(exitFile);
      }
      public void scanFile(File file) {
        if (file.isDirectory()) {
          File[] files = file.listFiles(new FileFilter() {
            public boolean accept(File pathname) {
              return pathname.isDirectory() || pathname.getPath().endsWith(".iso");
            }
          });
          for (File one : files)
            scanFile(one);
        } else {
          try {
            // 原子整型的incrementAndGet方法,以原子方式将当前值加 1,返回更新的值
            int index = rc.incrementAndGet();
            System.out.println("Read0: " + index + " " + file.getPath());
            // 添加到阻塞队列中
            queue.put(file);
          } catch (InterruptedException e) {
          }
        }
      }
    };
    // submit方法提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
    exec.submit(read);
    // 四个写线程
    for (int index = 0; index < 4; index++) {
      // write thread
      final int num = index;
      Runnable write = new Runnable() {
        String threadName = "Write" + num;
        public void run() {
          while (true) {
            try {
              Thread.sleep(randomTime());
              // 原子整型的incrementAndGet方法,以原子方式将当前值加 1,返回更新的值
              int index = wc.incrementAndGet();
              // 获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。
              File file = queue.take();
              // 队列已经无对象
              if (file == exitFile) {
                // 再次添加"标志",以让其他线程正常退出
                queue.put(exitFile);
                break;
              }
              System.out.println(threadName + ": " + index + " " + file.getPath());
            } catch (InterruptedException e) {
            }
          }
        }
      };
      exec.submit(write);
    }
    exec.shutdown();
  }
}

AtomicInteger使用总结

AtomicInteger是在使用非阻塞算法实现并发控制,在一些高并发程序中非常适合,但并不能每一种场景都适合,不同场景要使用使用不同的数值类。

以上就是本文关于Java AtomicInteger类的使用方法详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:java原生序列化和Kryo序列化性能实例对比分析 、关于Java企业级项目开发思想 、Java map存放数组并取出值代码详解 等,有什么问题可以随时留言,小编会及时回复大家。

原文地址是:http://www.piaodoo.com/thread-13234-1-2.html 丝袜控www.txdah.com 131www.buzc.org学习之外可赏心悦目有助更好地学习!

Java AtomicInteger类的使用方法详解_java - JAVA的更多相关文章

  1. Java File 类的使用方法详解

    Java File类的功能非常强大,利用Java基本上可以对文件进行所有的操作.本文将对Java File文件操作类进行详细地分析,并将File类中的常用方法进行简单介绍,有需要的Java开发者可以看 ...

  2. Java File 类的使用方法详解(转)

    转自:http://www.codeceo.com/article/java-file-class.html Java File类的功能非常强大,利用Java基本上可以对文件进行所有的操作.本文将对J ...

  3. Delphi中TStringList类常用属性方法详解

    TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 先把要讨论的几个属性列出来: 1.CommaText 2.Delim ...

  4. Python的Django框架中forms表单类的使用方法详解

    用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...

  5. 【Java】equals()与hashCode()方法详解 (转)

    java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...

  6. java:数组操作工具类 java.util.Arrays包 主要方法详解

    Arrays类位于Java.util包下,是一个对数组操作的工具类,现将Arrays类中的方法做一个总结(JDK版本:1.6.0_34).Arrays类中的方法可以分为八类: sort(对数组排序) ...

  7. java 中toString()方法详解

    1.toString()方法 Object类具有一个toString()方法,你创建的每个类都会继承该方法.它返回对象的一个String表示,并且对于调试非常有帮助.然而对于默认的toString() ...

  8. Java中hashCode与equal方法详解

    转载自http://blog.csdn.net/jiangwei0910410003/article/details/22739953 Java中的equals方法和hashCode方法是Object ...

  9. Java使用wait() notify()方法操作共享资源详解_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 Java多个线程共享资源: 1)wait().notify()和notifyAll()方法是本地方法,并且为final方 ...

随机推荐

  1. ntp同步报错解决

    服务端:192.168.1.204 主机名: www.test.com 客户端:192.168.1.206 主机名: www.test3.com 客户端同步服务端报错如下: [root@www etc ...

  2. 做筛选遍历时遇到的json字符串、json对象、json数组 三者之间的转换问题

    这个是后台对登录用户以及筛选条件的操作 @Override public List<SdSdPer> listResults(String sidx, String sord) { try ...

  3. Stream流实现斐波那契数列

    1.前言 我们都知道斐波那契数列有很多种实现方法,在jdk1.8以前没有流操作,只能通过递归或者迭代等其他方式来实现斐波那契数列, 但是jdk1.8以后,有了流操作,我们就可以使用流来实现斐波那契数列 ...

  4. USACO2.2 Preface Numbering【思维+打表】

    这道题乍一看没有什么思路,细看还是没有什么思路 嗯,细看还是可以看出些什么端倪. 不能复合嵌套什么的 总结一下就只有这样3种规则: 1.IXCM最多三个同样连续 加起来2.递减:加起来 注意VLD不连 ...

  5. 浅谈python中字典append 到list 后值的改变问题

    看一个例子 ? 1 2 3 4 d={'test':1} d_test=d d_test['test']=2 print d 如果你在命令行实践的话,会发现你改动的是d_test ,但是d 也跟着改变 ...

  6. 关于Eclipse及JDK安装过程中的一些问题

    一,环境变量的配置 1.配置CLASSPATH系统变量 CLASSPATH系统变量为类查找路径 ①.在使用javac进行编译时遇到import时候就会通过这个变量里面配置的路径去查找.如果配置的是目录 ...

  7. 二、Kubernetes_V1.10集群部署-master-etcd

    1.ETCD集群服务器: (1)172.18.6.39 (2)172.18.6.40 (3)172.18.6.41 1.安装etcd # yum -y install etcd 2.发布证书 cp - ...

  8. 思考--PostgreSQL在与mysql的比较中稍微弱势项

    PostgreSQL在与mysql的比较中稍微弱势项: 1.都是堆表,没有所谓的聚集索引表,其实问题不大,聚集索引表也只是在使用聚集索引那些列有加速,而且pg也有聚集索引,只不过要定期重建. 2.mv ...

  9. springBoot2.0使用@ImportResource引入spring配置文件.xml

    1. 编写spring配置文件.xml 这里是bean.xml <?xml version="1.0" encoding="UTF-8"?> < ...

  10. Python基础数据类型str字符串

    3.3字符串str ' ' 0 切片选取 [x:y] 左闭右开区间 [x:y:z] 选取x到y之间 每隔z选取一次(选取x,x+z,....) z为正 索引位置:x在y的左边 z为负 索引位置:x在y ...