综述

JDK从1.5开始提供了java.util.concurrent.atomic包。

通过包中的原子操作类能够线程安全地更新一个变量。

包含4种类型的原子更新方式:基本类型、数组、引用、对象中字段更新。

atomic包中的原子操作类基本上内部都是使用Unsafe类实现的,原子更新的实质其实就是获取内存偏移地址,对地址中的变量进行更新

关于Unsafe类,可以参考我的这篇博文【Java并发】Java中的Unsafe类

1.原子更新基本类型类

atomic包内包含AtomicBoolean、AtomicInteger、AtomicLong这3个类,以下以AtomicInteger进行讲解。

AtomicInteger是如何实现原子操作的?

是使用Unsafe类实现的,而Unsafe实现原子操作的原理是通过得到变量相对于对象示例的内存偏移地址,更新内存地址内的变量值。

下面是摘录的AtomicInteger的部分源码。

  1. /**
  2. * Atomically increments by one the current value.
  3. *
  4. * @return the previous value
  5. */
  6. public final int getAndIncrement() {
  7. return unsafe.getAndAddInt(this, valueOffset, 1);
  8. }
  9.  
  10. /**
  11. * Atomically decrements by one the current value.
  12. *
  13. * @return the previous value
  14. */
  15. public final int getAndDecrement() {
  16. return unsafe.getAndAddInt(this, valueOffset, -1);
  17. }
  18.  
  19. /**
  20. * Atomically adds the given value to the current value.
  21. *
  22. * @param delta the value to add
  23. * @return the previous value
  24. */
  25. public final int getAndAdd(int delta) {
  26. return unsafe.getAndAddInt(this, valueOffset, delta);
  27. }
  28.  
  29. /**
  30. * Atomically increments by one the current value.
  31. *
  32. * @return the updated value
  33. */
  34. public final int incrementAndGet() {
  35. return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
  36. }
  37.  
  38. /**
  39. * Atomically decrements by one the current value.
  40. *
  41. * @return the updated value
  42. */
  43. public final int decrementAndGet() {
  44. return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
  45. }
  46.  
  47. /**
  48. * Atomically adds the given value to the current value.
  49. *
  50. * @param delta the value to add
  51. * @return the updated value
  52. */
  53. public final int addAndGet(int delta) {
  54. return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
  55. } 

2.原子更新数组

atomic包内包含AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray这3个类,以下以AtomicIntegerArray进行讲解。

AtomicIntegerArray是如何实现原子操作的?

是使用Unsafe类实现的,而Unsafe实现原子操作的原理是通过得到变量相对于数组的内存偏移地址,更新内存地址内的变量值。

下面是摘录的AtomicIntegerArray的部分源码。

  1. /**
  2. * Atomically increments by one the element at index {@code i}.
  3. *
  4. * @param i the index
  5. * @return the previous value
  6. */
  7. public final int getAndIncrement(int i) {
  8. return getAndAdd(i, 1);
  9. }
  10.  
  11. /**
  12. * Atomically decrements by one the element at index {@code i}.
  13. *
  14. * @param i the index
  15. * @return the previous value
  16. */
  17. public final int getAndDecrement(int i) {
  18. return getAndAdd(i, -1);
  19. }
  20.  
  21. /**
  22. * Atomically adds the given value to the element at index {@code i}.
  23. *
  24. * @param i the index
  25. * @param delta the value to add
  26. * @return the previous value
  27. */
  28. public final int getAndAdd(int i, int delta) {
  29. return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);
  30. }
  31.  
  32. /**
  33. * Atomically increments by one the element at index {@code i}.
  34. *
  35. * @param i the index
  36. * @return the updated value
  37. */
  38. public final int incrementAndGet(int i) {
  39. return getAndAdd(i, 1) + 1;
  40. }
  41.  
  42. /**
  43. * Atomically decrements by one the element at index {@code i}.
  44. *
  45. * @param i the index
  46. * @return the updated value
  47. */
  48. public final int decrementAndGet(int i) {
  49. return getAndAdd(i, -1) - 1;
  50. }
  51.  
  52. /**
  53. * Atomically adds the given value to the element at index {@code i}.
  54. *
  55. * @param i the index
  56. * @param delta the value to add
  57. * @return the updated value
  58. */
  59. public final int addAndGet(int i, int delta) {
  60. return getAndAdd(i, delta) + delta;
  61. } 

3.原子更新引用

使用AtomicInteger只能原子更新一个变量,如果要原子更新多个变量,就需要将多个变量封装起来,原子更新对象引用。

atomic包内包含AtomicReference、AtomicReferenceFieldUpdater、AtomicUpdater这3个类,以下以AtomicIntegerArray进行讲解。

下面是摘录的AtomicReference的部分源码。

  1. /**
  2. * Atomically sets the value to the given updated value
  3. * if the current value {@code ==} the expected value.
  4. * @param expect the expected value
  5. * @param update the new value
  6. * @return {@code true} if successful. False return indicates that
  7. * the actual value was not equal to the expected value.
  8. */
  9. public final boolean compareAndSet(V expect, V update) {
  10. return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
  11. }
  12. /**
  13. * Atomically sets to the given value and returns the old value.
  14. *
  15. * @param newValue the new value
  16. * @return the previous value
  17. */
  18. @SuppressWarnings("unchecked")
  19. public final V getAndSet(V newValue) {
  20. return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
  21. }

4.原子更新字段类

用于更新类里的某个字段。

atomic包内包含AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference这3个类。

AtomicStampedReference 将整数值与引用关联起来,可以用于原子地更新数据和数据的版本号,可以解决CAS的ABA问题。

【Java并发】Java中的原子操作类的更多相关文章

  1. Java中的原子操作类

    转载: <ava并发编程的艺术>第7章 当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可 ...

  2. java并发编程:线程安全管理类--原子操作类--AtomicInteger

    在java并发编程中,会出现++,--等操作,但是这些不是原子性操作,这在线程安全上面就会出现相应的问题.因此java提供了相应类的原子性操作类. 1.AtomicInteger

  3. java中的原子操作类AtomicInteger及其实现原理

    /** * 一,AtomicInteger 是如何实现原子操作的呢? * * 我们先来看一下getAndIncrement的源代码: * public final int getAndIncremen ...

  4. Java并发编程系列-(3) 原子操作与CAS

    3. 原子操作与CAS 3.1 原子操作 所谓原子操作是指不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何context switch,也就是切换到另一个线程. 为了实 ...

  5. Java并发编程中的若干核心技术,向高手进阶!

    来源:http://www.jianshu.com/p/5f499f8212e7 引言 本文试图从一个更高的视角来总结Java语言中的并发编程内容,希望阅读完本文之后,可以收获一些内容,至少应该知道在 ...

  6. Java并发编程中的相关注解

    引自:http://www.cnblogs.com/phoebus0501/archive/2011/02/21/1960077.html Java并发编程中,用到了一些专门为并发编程准备的 Anno ...

  7. Java并发编程中的设计模式解析(二)一个单例的七种写法

    Java单例模式是最常见的设计模式之一,广泛应用于各种框架.中间件和应用开发中.单例模式实现起来比较简单,基本是每个Java工程师都能信手拈来的,本文将结合多线程.类的加载等知识,系统地介绍一下单例模 ...

  8. Java并发编程中线程池源码分析及使用

    当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...

  9. int是java.lang包中可用的类的名称

    int是java.lang包中可用的类的名称(x) int为基本数据类型,不是类

随机推荐

  1. SQL Server系统函数简介[转]

    一.字符转换函数1.ASCII()返回字符表达式最左端字符的ASCII 码值.在ASCII()函数中,纯数字的字符串可不用‘’括起来,但含其它字符的字符串必须用‘’括起来使用,否则会出错.2.CHAR ...

  2. 原生js:js获得当前选中的内容的字体大小

    利用currentStyle()和ComputedStyle() function getstyle(obj, key) {    if (obj.currentStyle) {        ret ...

  3. Centos6.5下DHCP服务器的安装和配置

    1.首先需要安装DHCP的软件包,使用yum进行安装 # yum install -y dhcp.x86_64  dhcp-devel.x86_64 2.将/usr/share/doc/dhcp-4. ...

  4. sqlserver----记录转载(行转列)、列转行、pivot、unpivot

    CREATE TABLE [StudentScores] ( ), --学生姓名 ), --科目 [Score] FLOAT, --成绩 ) 如果我想知道每位学生的每科成绩,而且每个学生的全部成绩排成 ...

  5. java操作mongoDB数据库的简单实例

    首先导入mongoDB的jar包 http://pan.baidu.com/s/1bnGMJRD //DataBase.java package com.mongodb.test; import ja ...

  6. 如何基于Go搭建一个大数据平台

    如何基于Go搭建一个大数据平台 - Go中国 - CSDN博客 https://blog.csdn.net/ra681t58cjxsgckj31/article/details/78333775 01 ...

  7. Career Planning:Developers Best Practices Tutorial

    This small tutorial is based on my past 16+ years of experience in software development industry. I ...

  8. MySQL日期时间字段

    mysql支持的日期时间类型有:DATETIME. TIMESTAMP.DATE.TIME.YEAR. 几种类型比较如下: DATETIME DATETIME 用于表示 年月日 时分秒,是 DATE和 ...

  9. 012-JDK可视化监控工具-jstack

    一.概述 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...

  10. Angular学习笔记—Rxjs、Promise的区别

    Promises: 异步操作完成或失败时处理单个事件 不可取消 代码可读性强,有try/catch Observables: 可持续监听和响应多个事件 可取消订阅 支持map, filter, red ...