本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。

并发编程系列博客传送门


原子类型字段更新器

java.util.concurrent.atomic中,原子类型字段更新器有以下三种:

  • AtomicIntegerFieldUpdater:基于反射的工具类,可以原子性的更新指定对象的指定int类型字段。
  • AtomicLongFieldUpdater:基于反射的工具类,可以原子性的更新指定对象的指定long类型字段。
  • AtomicReferenceFieldUpdater:基于反射的工具类,可以原子性的更新指定对象的指定应用类型字段。

使用规则

原子类型字段更新器在内部通过Unsafe类的native方法保证操作的原子性。

关于原子类型字段更新器的使用需要注意以下几个方面:

  • 字段必须是volatile类型的,用于保证可见性。
  • 字段和字段更新器的访问类型(public/protected/private)必须一致。
  • 字段只能是实例变量,不能是类变量(static)。
  • 字段不能是final的变量,这样的字段不可修改。
  • 如果要处理Integer和Long类型,则需要使用AtomicReferenceFieldUpdater

使用列子(以AtomicIntegerFieldUpdater为列)

public class AtomicIntegerFieldUpdaterTest {
private static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater.newUpdater(User.class, "old"); public static void main(String[] args) {
// 设置柯南的年龄是10岁
User conan = new User("conan",10);
// 柯南长了一岁,但是仍然会输出旧的年龄
System.out.println(a.getAndIncrement(conan));
// 输出柯南现在的年龄
System.out.println(a.get(conan));
} public static class User {
private String name;
public volatile int old; public User(String name,int old) {
this.name = name;
this.old = old;
} public String getName() {
return name;
} public int getOld() {
return old;
}
}
}

方法说明

首先学习上述三种原子类型字段更新器的通用方法,这些方法如下:

  • 构造器:只有一个无参protected的构造函数,并不可用。
  • newUpdater(fieldClass,fieldName):原子类型字段更新器提供的一个静态泛型方法,用于创建和返回指定字段和指定类型的原子类型字段更新器实例对象。
  • get(obj):赋值,具有原子性和可见性。
  • set(obj):取值,具有原子性和可见性。
  • lazySet(obj,newValue):赋值,具有原子性,不具备可见性。
  • getAndSet(obj,newValue):赋值并返回旧值,具有原子性和可见性。
  • compareAndSet(obj,expect,update):如果当前是期望值则赋值并返回赋值成功与否,具有原子性和可见性。
  • weakCompareAndSet(obj,expect,update):与compareAndSet(obj,expect,update)类似。

原子类型字段更新器的通用方法与普通原子类型的通用方法类似,唯一的区别在于多了一个参数:obj(被修改的字段的所属对象)。

AtomicIntegerFieldUpdater和AtomicLongFieldUpdater的独有方法,下面这些方法AtomicReferenceFieldUpdater类没有:

  • getAndAdd(obj):增量计算并返回旧值,具有原子性和可见性。
  • addAndGet(obj):增量计算并返回新值,具有原子性和可见性。
  • getAndIncrement(obj):自增并返回旧值,类似i ++,具有原子性和可见性。
  • incrementAndGet(obj):自增并返回新值,类似++ i,具有原子性和可见性。
  • getAndDecrement(obj):自减并返回旧值,类似i --,具有原子性和可见性。
  • decrementAndGet(obj):自减并返回新值,类似-- i,具有原子性和可见性。

原子类型字段更新器AtomicXxxxFieldUpdater的更多相关文章

  1. Java原子属性更新器AtomicReferenceFieldUpdater的使用

    AtomicReferenceFieldUpdater是基于反射的工具类,用来将指定类型的指定的volatile引用字段进行原子更新,对应的原子引用字段不能是private的.通常一个类volatil ...

  2. Sqlserver更新数据表xml类型字段内容某个节点值的脚本

    GO USE [JC2010_MAIN_DB] 1.新建备份表JobObjectVersion_JCSchemVersion_BCK) GO IF EXISTS (SELECT * FROM sys. ...

  3. Dynamics CRM 通过Odata创建及更新记录各类型字段的赋值方式

    CRM中通过Odata方式去创建或者更新记录时,各种类型的字段的赋值方式各不相同,这里转载一篇博文很详细的列出了各类型字段赋值方式,以供后期如有遗忘再次查询使用. http://luoyong0201 ...

  4. Java更新Oracle的clob类型字段

    Java更新Oracle的clob类型字段 1.查询该clob字段 2.处理该clob字段查询结果 3.更新该clob字段查询结果 1.查询该clob字段 <select id="se ...

  5. 原子类型的使用&Unsafe&CAS

    在项目中也经常可以见到原子类型(AtomicXXX)的使用,而且AtomicXXX常用来代替基本类型或者基本类型的包装类型,因为其可以在不加同步锁的情况下保证线程安全(只对于原子操作). 下面以Ato ...

  6. 深入解析Java AtomicInteger 原子类型

    深入解析Java AtomicInteger原子类型 在进行并发编程的时候我们需要确保程序在被多个线程并发访问时可以得到正确的结果,也就是实现线程安全.线程安全的定义如下: 当多个线程访问某个类时,不 ...

  7. 深入解析Java AtomicInteger原子类型

    深入解析Java AtomicInteger原子类型 在并发编程中,需要确保当多个线程同时访问时,程序能够获得正确的结果,即实现线程安全.线程安全性定义如下: 当多个线程访问一个类时,无论如何调度运行 ...

  8. 【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象

    在实际更新Mongo对象时发现,原有的更新代码无法更新复杂的数据类型对象.恰好看到张占岭老师有对该方法做相关的改进,因此全抄了下来. 总的核心思想就是运用反射与递归,对对象属性一层一层挖掘下去,循环创 ...

  9. SQL Server中TEXT类型字段值在数据库中追加字符串方法

    在数据上我们往往会遇到ntext大文本类型,这种类型如果和 nvarchar类型相加会出现问题,所以有一中方法可以解决这种问题. 使用的sql   函数: TEXTPTR:返回要更新的 text.nt ...

随机推荐

  1. java中栈内存与堆内存(JVM内存模型)

    java中栈内存与堆内存(JVM内存模型) Java中堆内存和栈内存详解1 和 Java中堆内存和栈内存详解2 都粗略讲解了栈内存和堆内存的区别,以及代码中哪些变量存储在堆中.哪些存储在栈中.内存中的 ...

  2. Python—处理Excel表格

    一.使用xlrd和xlwt这两个库来处理excel,即xlrd是读excel的库,xlwt是写excel的库 1.使用 xlrd 读取Excel数据 # -*- coding:utf-8 -*- im ...

  3. javascript 在页面不刷新的情况下 其中的变量时不会被初始化的

    因此可以根据这个原理做出一些效果,例如 <html>    <head>        <meta charset="utf-8" />     ...

  4. 【Unity】鼠标指向某物体,在其上显示物体的名字等等等等信息

    之前一直用NGUI HUD Text插件做这个功能,感觉一个小功能就导一个插件进来简直丧心病狂.然后就自己写了一个~ Camera cam;//用于发射射线的相机 Camera UIcam;//UI层 ...

  5. 发送短信-----用restful 校验规则

    我们的需求如下 1. 获取手机号 . 手机格式校验 . 生成随机验证码 . 验证码发送到手机上 . 把验证码+手机号保留(30s过期) 复习 我们在有表的情况下的序列化 class MessageSe ...

  6. C++面试常见问题——10派生类的构造与析构

    派生类的构造与析构 派生类的构造 派生时构造函数与析构函数不会被继承,需要重新定义派生类的构造函数与析构函数.派生类对象包含了基类对象的值,创建派生类时首先会调用基类的构造函数,若派生类中含有其它类对 ...

  7. string.xml中的空格

    <string name="userName">    用    户    名</string>

  8. 031、Java中偶数偶数的判断方法

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  9. Spark 资料整理

    http://jerryshao.me/architecture/2013/10/08/spark-storage-module-analysis/ http://blog.csdn.net/aliv ...

  10. mysql 模糊查询中包含特殊字符查询