Java中的13个原子操作类

  当程序更新一个变量时, 如果多线程同时更新这个变量, 可能得到期望之外的值, 比如变量 i=l, A 线程更新 i+l, B 线程也更新 1叶, 经过两个线程操作之后可能 i 不等于3,而是等于2。 因为A和B线程在更新变量i 的时候拿到的i 都是1,这就是线程不安全的更新操作, 通常我们会使用 synchronized 来解决这个问题, synchronized 会保证多线程不会同时更 新变量i。
  而 Java 从 JDK1.5开始提供了java.util.concurrent.atomic 包(以下简称 Atomic 包), 这个包中的原子操作类提供了一种用法简单、 性能高效、 线程安全地更新一个变量的方式。
  因为变量的类型有很多种, 所以在 Atomic 包里一共提供了 13 个类, 属于4 种类型的原子更新方式, 分别是原子更新基本类型、 原子更新数组、 原子更新引用和原子更新属性(字段) 。 Atomic 包里的类基本都是使用 Unsafe 实现的包装类。

1.原子更新基本类型类

  使用原子的方式更新基本类型, Atomic 包提供了以下 3 个类。
  AtomicBoolean :原子更新布尔类型。
  Atomiclnteger :原子更新整型。
  AtomicLong:原子更新长整型。
  以上3个类提供的方法几乎一模一样,我们以AtomicInteger为例说明一下:
  int addAndGet ( int delta ): 以原子方式将输入的数值与实例中的值( Atomiclnteger 里
的 value )相加, 并返回结果。
  boolean compareAndSet ( int expect, int update ):如果输入的数值等于预期值, 则以原
子方式将该值设置为输入的值。
  int getAndlncrement():以原子方式将当前值加 l , 注意, 这里返回的是自增前的值。
  void IazySet ( int newValue ):最终会设置成 newValue,使用 lazySet 设置值后, 可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
  int getAndSet (int newValue ):以原子方式设置为newValue 的值, 并返回旧值。

2. 原子更新数组

  AtomicLongArray:原子更新长整型数组里的元素。
  AtomicReferenceArray:原子更新引用类型数组里的元素。
  AtomicintegerArray类主要是提供原子的方式更新数组里的整型,其常用方法如下。
    intaddAndGet ( int i, int delta):以原子方式将输入值与数组中索引i的元素相加。
    boolean compareAndSet ( int i, int expect, int update):如果当前值等于预期值,则以原子方式将数组位置i的元素设置成update值。

3. 原子引用类型

  原子更新基本类型的Atomiclnteger,只能更新一个变量,如果要原子更新多个变量,就需要使用这个原子更新引用类型提供的类。Atomic包提供了以下3个类。
  AtomicReference:原子更新引用类型。
  AtomicReferenceFieldU pdater:原子更新引用类型里的字段。
  AtomicMarkableReference:原子更新带有标记位的引用类型。可以原子更新一个布尔类型的标记位和引用类型。构造方法是AtomicMarkableReference ( V initia!Ref, boolean initia!Mark)。

4.原子更新字段类

  如果需原子地更新某个类里的某个字段时,就需要使用原子更新字段类, Atomic 包提供了以下3个类进行原子字段更新。
  AtomiclntegerFieldUpdater :原子更新整型的字段的更新器。
  AtomicLongFieldUpdater :原子更新长整型宇段的更新器。
  AtomicStampedReference :原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更新数据和数据的版本号,可以解决使用CAS进行原子更新时可能出现的ABA问题。
  要想原子地更新字段类需要两步。第一步,因为原子更新宇段类都是抽象类, 每次使用的时候必须使用静态方法 newUpdater()创建一个更新器,并且需要设置想要更新的类和属性。第二步,更新类的字段(属性)必须使用 public volatile 修饰符。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,183评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,850评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,766评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,854评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,871评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,457评论 1 311
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,999评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,914评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,465评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,543评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,675评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,354评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,029评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,514评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,616评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,091评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,685评论 2 360

推荐阅读更多精彩内容