引用地址:http://blog.csdn.net/xh16319/article/details/17056767

在java6以后我们不但接触到了Lock相关的锁,也接触到了很多更加乐观的原子修改操作,也就是在修改时我们只需要保证它的那个瞬间是安全的即可,经过相应的包装后可以再处理对象的并发修改,以及并发中的ABA问题,本文讲述Atomic系列的类的实现以及使用方法,其中包含:

基本类:AtomicInteger、AtomicLong、AtomicBoolean;

引用类型:AtomicReference、AtomicReference的ABA实例、AtomicStampedRerence、AtomicMarkableReference;

数组类型:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray

属性原子修改器(Updater):AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater

在使用Atomic系列前,我们需要先知道一个东西就是Unsafe类,全名为:sun.misc.Unsafe,这个类包含了大量的对C代码的操作,包括很多直接内存分配以及原子操作的调用,而它之所以标记为非安全的,是告诉你这个里面大量的方法调用都会存在安全隐患,需要小心使用,否则会导致严重的后果,例如在通过unsafe分配内存的时候,如果自己指定某些区域可能会导致一些类似C++一样的指针越界到其他进程的问题,不过它的具体使用并不是本文的重点,本文重点是Atomic系列的内容大多会基于unsafe类中的以下几个本地方法来操作:

对象的引用进行对比后交换,交换成功返回true,交换失败返回false,这个交换过程完全是原子的,在CPU上计算完结果后,都会对比内存的结果是否还是原先的值,若不是,则认为不能替换,因为变量是volatile类型所以最终写入的数据会被其他线程看到,所以一个线程修改成功后,其他线程就发现自己修改失败了。

参数1:对象所在的类本身的对象(一般这里是对一个对象的属性做修改,才会出现并发,所以该对象所存在的类也是有一个对象的)

参数2:这个属性在这个对象里面的相对便宜量位置,其实对比时是对比内存单元,所以需要属性的起始位置,而引用就是修改引用地址(根据OS、VM位数和参数配置决定宽度一般是4-8个字节),int就是修改相关的4个字节,而long就是修改相关的8个字节。

获取偏移量也是通过unsafe的一个方法:objectFieldOffset(Fieldfield)来获取属性在对象中的偏移量;静态变量需要通过:staticFieldOffset(Field field)获取,调用的总方法是:fieldOffset(Fieldfield)

参数3:修改的引用的原始值,用于对比原来的引用和要修改的目标是否一致。

参数4:修改的目标值,要将数据修改成什么。

  1. public final native boolean compareAndSwapObject(Object paramObject1, long paramLong, Object paramObject2, Object paramObject3);
  2. public final native boolean compareAndSwapInt(Object paramObject, long paramLong, int paramInt1, int paramInt2);

#对long的操作,要看VM是否支持对Long的CAS,因为有可能VM本身不支持,若不支持,此时运算会变成Lock方式,不过现在VM都基本是支持的而已。

  1. public final native boolean compareAndSwapLong(Object paramObject, long paramLong1, long paramLong2, long paramLong3);

我们不推荐直接使用unsafe来操作原子变量,而是通过java封装好的一些类来操作原子变量。

本文最后要介绍的部分为Updater也就是修改器,它算是Atomic的系列的一个扩展,Atomic系列是为你定义好的一些对象,你可以使用,但是如果是别人已经在使用的对象会原先的代码需要修改为Atomic系列,此时若全部修改类型到对应的对象相信很麻烦,因为牵涉的代码会很多,此时java提供一个外部的Updater可以对对象的属性本身的修改提供类似Atomic的操作,也就是它对这些普通的属性的操作是并发下安全的,分别由:AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceUpdater,这样操作后,系统会更加灵活,也就是可能那些类的属性只是在某些情况下需要控制并发,很多时候不需要,但是他们的使用通常有以下几个限制:

限制1:操作的目标不能是static类型,前面说到unsafe的已经可以猜测到它提取的是非static类型的属性偏移量,如果是static类型在获取时如果没有使用对应的方法是会报错的,而这个Updater并没有使用对应的方法。

限制2:操作的目标不能是final类型的,因为final根本没法修改。

限制3:必须是volatile类型的数据,也就是数据本身是读一致的。

限制4:属性必须对当前的Updater所在的区域是可见的,也就是private如果不是当前类肯定是不可见的,protected如果不存在父子关系也是不可见的,default如果不是在同一个package下也是不可见的。

实现方式:通过反射找到属性,对属性进行操作,但是并不是设置accessable,所以必须是可见的属性才能操作。

AtomicInteger相关类的更多相关文章

  1. Android随笔之——Android时间、日期相关类和方法

    今天要讲的是Android里关于时间.日期相关类和方法.在Android中,跟时间.日期有关的类主要有Time.Calendar.Date三个类.而与日期格式化输出有关的DateFormat和Simp ...

  2. 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类

    21_BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类 BasicTaskScheduler基本任务调度器 BasicTaskScheduler基 ...

  3. 8 延时队列相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  4. 4 Handler相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. Handler相关类概述 处理程序相关类一共有三个,其没有派生继承关系,但是其有友元关系和使用关系 ...

  5. MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)

    前面讲了模态对话框和非模态对话框,本节来将一种特殊的对话框--属性页对话框. 属性页对话框的分类 属性页对话框想必大家并不陌生,XP系统中桌面右键点属性,弹出的就是属性页对话框,它通过标签切换各个页面 ...

  6. android 6.0 SDK中删除HttpClient的相关类的解决方法

    一.出现的情况 在eclipse或 android studio开发, 设置android SDK的编译版本为23时,且使用了httpClient相关类的库项目:如android-async-http ...

  7. Android 6.0删除Apache HttpClient相关类的解决方法

    相应的官方文档如下: 上面文档的大致意思是,在Android 6.0(API 23)中,Google已经移除了Apache HttpClient相关的类,推荐使用HttpUrlConnection. ...

  8. List 接口以及实现类和相关类源码分析

    List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...

  9. Web---演示Servlet的相关类、表单多参数接收、文件上传简单入门

    说明: Servlet的其他相关类: ServletConfig – 代表Servlet的初始化配置参数. ServletContext – 代表整个Web项目. ServletRequest – 代 ...

随机推荐

  1. Protocol buffers--python 实践(一) 简介以及安装与使用

    由于最近对grpc产生了浓厚的兴趣,但是那是一整套东西,看了一下用到的东西不少,所以抽丝剥茧先写写这几天调研的protocol buffer -python的收获. 简介: 以下引用自官方首页文档: ...

  2. Apache 隐藏入口文件以及防盗链.htaccess 文件

    Apache 隐藏入口文件以及防盗链.htaccess 文件 RewriteEngine on # 隐藏入口文件 RewriteCond %{REQUEST_FILENAME} !-d Rewrite ...

  3. Openlayers实现第一张地图

    <html><head><title>OpenLayers Hello World</title> <style type="text/ ...

  4. ArcEngine部分工作总结

    Arcengine工作总结地物点查询本部分可以在一个窗体中实现,也可以在两个窗体中实现.由于工作要求本人是在两个窗体中实现的:弹出窗体的名称为FormQuery主窗体单机查询时间的代码FormQuer ...

  5. 反射技术在Android中的应用

    本博客转自:http://blog.csdn.net/tiefeng0606/article/details/51700866 动态语言: 一般认为在程序运行时,允许改变程序结构或变量类型,这种语言称 ...

  6. 冯如杯day1

    day1 今天尝试配置了seetaface工程 主要按照这个网址中提示的步骤配置seetaface 第一步安装并配置OpenCV 按照这个网址进行配置,结果遇到了这样的错误 无法启动此程序,因为计算机 ...

  7. Yii -- framework 目录结构说明

    base 底层的类库文件 caching 所有缓存方法 cli 项目生成脚本 collecions 用PHP语言构造传统OO语言的数据存储单元.如队列,栈,哈希等等 console yii控制台 db ...

  8. matlab unique 顺序不变

    对于一个向量,使用unique去重后会自动排序,为了保持原顺序: A = [5,1,8,5,2,8,3,9,6,1];[i,j] = unique(A,'first');B = A(sort(j)); ...

  9. UIImageView控件

    UIImageView是用于显示图像的,在iOS开发中,我们无需专门去写什么代码,不需要检查设备的类型,只需要把1x.2x.3x的图像添加到项目中,图像视图会自动的在正确的时间加载正确的图像. (1) ...

  10. readln

    常用于暂停程序的运行!可以不带参数,read必须带参数; 使用原则: 1.没有特殊需要,一个程序中避免同时使用read 和readln: 2.尽量使用readln语句来输入数据,一个数据行对应一个re ...