java通常的代码无法直接使用操作底层的硬件,为了使java具备该能力,增加了Unsafe类

java的并发包中底层大量的使用这个类的功能,了解这个类有助于了解java 并发包,理解为什么并发包中的类的并发性能为什么会比使用synchronized好

Atomic包介绍

在Atomic包里一共有12个类,四种原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新字段。Atomic包里的类基本都是使用Unsafe实现的包装类。

原子更新基本类型类

用于通过原子的方式更新基本类型,Atomic包提供了以下三个类:

  • AtomicBoolean:原子更新布尔类型。
  • AtomicInteger:原子更新整型。
  • AtomicLong:原子更新长整型。

AtomicInteger的常用方法如下:

  • int addAndGet(int delta) :以原子方式将输入的数值与实例中的值(AtomicInteger里的value)相加,并返回结果
  • boolean compareAndSet(int expect, int update) :如果输入的数值等于预期值,则以原子方式将该值设置为输入的值。
  • int getAndIncrement():以原子方式将当前值加1,注意:这里返回的是自增前的值。
  • void lazySet(int newValue):最终会设置成newValue,使用lazySet设置值后,可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
  • int getAndSet(int newValue):以原子方式设置为newValue的值,并返回旧值。

AtomicInteger的demo:

  1. import java.util.concurrent.atomic.AtomicInteger;
  2.  
  3. public class Main {
  4. static Integer a=3;
  5. static AtomicInteger ai = new AtomicInteger(a);
  6. public static void main(String[] args) {
  7. System.out.println(ai.getAndIncrement());
  8. System.out.println(ai.get());
  9. System.out.println(a);
  10. }
  11. }
  1. 3
  2. 4
  3. 3

原子更新数组类

通过原子的方式更新数组里的某个元素,Atomic包提供了以下三个类:

  • AtomicIntegerArray:原子更新整型数组里的元素。
  • AtomicLongArray:原子更新长整型数组里的元素。
  • AtomicReferenceArray:原子更新引用类型数组里的元素。

AtomicIntegerArray类主要是提供原子的方式更新数组里的整型,其常用方法如下

  • int addAndGet(int i, int delta):以原子方式将输入值与数组中索引i的元素相加。
  • boolean compareAndSet(int i, int expect, int update):如果当前值等于预期值,则以原子方式将数组位置i的元素设置成update值。

代码:

  1. import java.util.concurrent.atomic.AtomicIntegerArray;
  2.  
  3. public class Main {
  4. static int[] value = new int[] { 1, 2 };
  5.  
  6. static AtomicIntegerArray ai = new AtomicIntegerArray(value);
  7.  
  8. public static void main(String[] args) {
  9. ai.getAndSet(0, 3);
  10. System.out.println(ai.get(0));
  11. System.out.println(value[0]);
  12. System.out.println(ai.get(1));
  13. ai.getAndSet(1,5);
  14. System.out.println(ai.get(1));
  15. }
  16. }
  1. 3
  2. 1
  3. 2
  4. 5

AtomicIntegerArray类需要注意的是,数组value通过构造方法传递进去,然后AtomicIntegerArray会将当前数组复制一份,所以当AtomicIntegerArray对内部的数组元素进行修改时,不会影响到传入的数组。

原子更新引用类型

原子更新基本类型的AtomicInteger,只能更新一个变量,如果要原子的更新多个变量,就需要使用这个原子更新引用类型提供的类。Atomic包提供了以下三个类:

  • AtomicReference:原子更新引用类型。
  • AtomicReferenceFieldUpdater:原子更新引用类型里的字段。
  • AtomicMarkableReference:原子更新带有标记位的引用类型。可以原子的更新一个布尔类型的标记位和引用类型。构造方法是AtomicMarkableReference(V initialRef, boolean initialMark)

代码:

  1. import java.util.concurrent.atomic.AtomicReference;
  2.  
  3. public class Main {
  4. public static AtomicReference<User> atomicUserRef = new AtomicReference<User>();
  5.  
  6. public static void main(String[] args) {
  7. User user = new User("conan", 15);
  8. atomicUserRef.set(user);
  9. User updateUser = new User("Shinichi", 17);
  10. atomicUserRef.compareAndSet(user, updateUser);
  11. System.out.println(atomicUserRef.get().getName());
  12. System.out.println(atomicUserRef.get().getOld());
  13. System.out.println(user.getName());
  14. System.out.println(user.getOld());
  15. }
  16.  
  17. static class User {
  18. private String name;
  19. private int old;
  20.  
  21. public User(String name, int old) {
  22. this.name = name;
  23. this.old = old;
  24. }
  25.  
  26. public String getName() {
  27. return name;
  28. }
  29.  
  30. public int getOld() {
  31. return old;
  32. }
  33. }
  34. }
  1. Shinichi
  2. 17
  3. conan
  4. 15

原子更新字段类

如果我们只需要某个类里的某个字段,那么就需要使用原子更新字段类,Atomic包提供了以下三个类:

  • AtomicIntegerFieldUpdater:原子更新整型的字段的更新器。
  • AtomicLongFieldUpdater:原子更新长整型字段的更新器。
  • AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更数据和数据的版本号,可以解决使用CAS进行原子更新时,可能出现的ABA问题。

原子更新字段类都是抽象类,每次使用都时候必须使用静态方法newUpdater创建一个更新器。原子更新类的字段的必须使用public volatile修饰符。

代码:

  1. import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
  2.  
  3. public class Main {
  4. private static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater
  5. .newUpdater(User.class, "old");
  6.  
  7. public static void main(String[] args) {
  8. User conan = new User("conan", 10);
  9. System.out.println(a.getAndIncrement(conan));
  10. System.out.println(a.get(conan));
  11. System.out.println(conan.getOld());
  12. }
  13.  
  14. public static class User {
  15. private String name;
  16. public volatile int old;
  17.  
  18. public User(String name, int old) {
  19. this.name = name;
  20. this.old = old;
  21. }
  22.  
  23. public String getName() {
  24. return name;
  25. }
  26.  
  27. public int getOld() {
  28. return old;
  29. }
  30. }
  31. }
  1. 10
  2. 11
  3. 11

http://ifeve.com/java-atomic/

http://blog.csdn.net/zhangerqing/article/details/43057799

Java中的Atomic包使用指南的更多相关文章

  1. Java中的Atomic包

    Atomic包的作用 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心 Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作: 关于CAS compare ...

  2. JDK中的Atomic包中的类及使用

    引言 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CPU ...

  3. Java并发—原子类,java.util.concurrent.atomic包(转载)

    原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...

  4. java中常用的包、类、以及包中常用的类、方法、属性----sql和text\swing

    java中常用的包.类.以及包中常用的类.方法.属性 常用的包 java.io.*; java.util.*; java.lang.*; java.sql.*; java.text.*; java.a ...

  5. Java:多线程,java.util.concurrent.atomic包之AtomicInteger/AtomicLong用法

    1. 背景 java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题. 在Java语言中,增量操作符(++)不是原子的,也就 ...

  6. java中的Atomic类

    文章目录 问题背景 Lock 使用Atomic java中的Atomic类 问题背景 在多线程环境中,我们最常遇到的问题就是变量的值进行同步.因为变量需要在多线程中进行共享,所以我们必须需要采用一定的 ...

  7. java.util.concurrent.atomic 包详解

    Atomic包的作用: 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心: Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作 关于CAS compar ...

  8. JavaSE&&JavaEE&&JavaME的区别【Java中常用的包结构】

    一.javaEEJavaSEJavaME用的同一个jar包吗? javaEE JavaSE javaME 用的JDK是同一个,开发j2SE工程的话只要有JDK就可以了,开发J2EE工程和J2ME工程除 ...

  9. Java中常见的包

    目录 JDK自带的包 第三方包 JDK自带的包 JAVA提供了强大的应用程序接口,既JAVA类库.他包含大量已经设计好的工具类,帮助程序员进行字符串处理.绘图.数学计算和网络应用等方面的工作.下面简单 ...

随机推荐

  1. C语言中字符串结束符'\0'

    转自:http://www.cnblogs.com/kaituorensheng/archive/2013/12/09/3464462.html 本质 '\0'就是8位的00000000,因为字符类型 ...

  2. 在SQL SERVER中实现RSA加解密函数(第一版)

    /*************************************************** 作者:herowang(让你望见影子的墙) 日期:2010.1.1 注:   转载请保留此信息 ...

  3. 数据库错误:check the manual that corresponds to your MySQL server version for the right sy

    检查对应到您的MySQL服务器版本附近使用正确的语法手册 数据库插入的时候出现上述问题,总结了两方面原因: 1.语法错误,这是百度之得到的大部分结果,但是没有解决我的问题 2.仔细观察我的sql语句, ...

  4. Spring快速入门

    什么是Spring Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架 分层 SUN提供的EE的三层结构:web层.业务层.数据访问层(持久层/集成层) Strut ...

  5. CSS3绘制404页面

    标题有点噱了...最近在做一个交通有关的项目, 想做一个类似标志牌的404, 所以就有了这个. 只用的CSS3中的旋转, 效果如下 上代码: <!DOCTYPE html> <htm ...

  6. 字典树 - A Poet Computer

    The ACM team is working on an AI project called (Eih Eye Three) that allows computers to write poems ...

  7. Windows Phone Sliding Effect

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" Backgro ...

  8. MySQL黑科技用法总结(持续更新)

    1.利用set插入数值 insert [into] 表名 set 列=值.  2.利用select对字段进行测试 ) ,并且有2条记录 ',num1+1的计算结果 tips:相等返回1,否则返回0 f ...

  9. *HDU3339 最短路+01背包

    In Action Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  10. ORA-12519: TNS:no appropriate service handler found 解决(转)

    可能是数据库上当前的连接数目已经超过了它能够处理的最大值. select count(*) from v$process --当前的连接数 select value from v$parameter  ...