在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口
[java] view plaincopy
  1. import java.util.concurrent.atomic.AtomicInteger;
  2. public class AtomicIntegerTest {
  3. public AtomicInteger inc = new AtomicInteger();
  4. public void increase() {
  5. inc.getAndIncrement();//i++操作
  6. //inc.getAndDecrement();//i--操作
  7. }
  8. public static void main(String[] args) {
  9. final AtomicIntegerTest test = new AtomicIntegerTest();
  10. for (int i = 0; i < 10; i++) {
  11. new Thread() {
  12. public void run() {
  13. for (int j = 0; j < 1000; j++)
  14. test.increase();
  15. };
  16. }.start();
  17. }
  18. while (Thread.activeCount() > 1)
  19. // 保证前面的线程都执行完
  20. Thread.yield();
  21. System.out.println(test.inc);
  22. }
  23. }

 可以发现结果都是10000,也就是说AtomicInteger是线程安全的。

值得一看。

这里,我们来看看AtomicInteger是如何使用非阻塞算法来实现并发控制的。

AtomicInteger的关键域只有一下3个:

[java] view plaincopy
  1. // setup to use Unsafe.compareAndSwapInt for updates
  2. private static final Unsafe unsafe = Unsafe.getUnsafe();
  3. private static final long valueOffset;
  4. private volatile int value;

这里, unsafe是Java提供的获得对对象内存地址访问的类,注释已经清楚的写出了,它的作用就是在更新操作时提供“比较并替换”的作用。实际上就是AtomicInteger中的一个工具。

valueOffset是用来记录value本身在内存的便宜地址的,这个记录,也主要是为了在更新操作在内存中找到value的位置,方便比较。

注意:value是用来存储整数的时间变量,这里被声明为volatile,就是为了保证在更新操作时,当前线程可以拿到value最新的值(并发环境下,value可能已经被其他线程更新了)。

这里,我们以自增的代码为例,可以看到这个并发控制的核心算法:

[java] view plaincopy
  1. /**
  2. * Atomically increments by one the current value.
  3. *
  4. * @return the updated value
  5. */
  6. public final int incrementAndGet() {
  7. for (;;) {
  8. //这里可以拿到value的最新值
  9. int current = get();
  10. int next = current + 1;
  11. if (compareAndSet(current, next))
  12. return next;
  13. }
  14. }
  15. public final boolean compareAndSet(int expect, int update) {
  16. //使用unsafe的native方法,实现高效的硬件级别CAS
  17. return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
  18. }

好了,看到这个代码,基本上就看到这个类的核心了。相对来说,其实这个类还是比较简单的。可以参考http://hittyt.iteye.com/blog/1130990

多线程1:AtomicInteger的使用,多线程叠加或叠减相关推荐

  1. 5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结

    5天玩转C#并行和多线程编程 -- 第五天 多线程编程大总结 5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 -- 第一天 认识Parallel 5天玩转C#并行和多线程编程 ...

  2. java第七章多线程_第七章 多线程

    7 多线程 7.1 进程和线程 1.进程进程是一个正在执行中的程序 每一个进程都有一个执行顺序,该顺序是一个执行路径,或者叫做一个控制单元 2.线程线程就是进程中的一个独立控制单元 线程在控制着进程的 ...

  3. 秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据

    本文配套程序下载地址为:http://download.csdn.net/detail/morewindows/5136035 转载请标明出处,原文地址:http://blog.csdn.net/mo ...

  4. java多线程的实现方式_Java 多线程(一)——多线程的实现方式

    一.前言 Java 异常的处理方式与自定义异常 我们已经讲完了,从今天开始我们来学习多线程. 二.与多线程相关的概念 2.1.并发与并行并发:指两个或多个事件在同一个时间段内发生,具体如下图所示: 并 ...

  5. VS中的多线程(/MT)、多线程调试(/MTd)、多线程DLL(/MD)、多线程调试DLL(/MDd)的区别(转载)

    转载链接https://blog.csdn.net/qq_33757398/article/details/82156956 一种语言的开发环境往往会附带有语言库,这些库就是对操作系统的API的包装, ...

  6. java多线程采集+线程同步-【多线程数据采集之四】

    前些日子讲解了java数据抓取, 今天就讲解最核心的. java多线程数据抓取. java多线程采集+数据同步+线程同步[多线程数据采集之四] 主要讲解多线程抓取,多线程同步,多线程启动,控制等操作. ...

  7. 多线程编程(1): python对多线程的支持

    python多线程编程(1): python对多线程的支持 前面介绍过多线程的基本概念,理解了这些基本概念,掌握python多线程编程就比较容易了. 在开始之前,首先要了解一下python对多线程的支 ...

  8. .NET异步和多线程系列(四)- 多线程异常处理、线程取消、多线程的临时变量问题、线程安全和锁lock

    本文是.NET异步和多线程系列第四章,主要介绍的是多线程异常处理.线程取消.多线程的临时变量问题.线程安全和锁lock等. 一.多线程异常处理 多线程里面抛出的异常,会终结当前线程,但是不会影响别的线 ...

  9. 易语言 mysql多线程_易语言数据库多线程 易语言数据库教程

    为什么易语言两个线程同时对一个MYSQL数据? 数据库有自己的连接锁定机制.如果同一台机器使用同一接口插入,则多线程和单线程是相同的. 除非您有多个数据库服务器,然后使用多线程来完成上述工作,否则效率 ...

最新文章

  1. studio添加依赖工程方法
  2. 和计算机互动英语,计算机专业英语互动教学方法探讨
  3. ValueError: Program dot not found in path.python下运行pygraphviz出现报错
  4. 王昶衡(帮别人名字作诗)
  5. 解决JupyterLab/JupyterNotebook安装pycherts后依旧报错报错 ModuleNotFoundError: No module named ‘pyecharts‘
  6. 达梦数据库如何连接MySQL_如何创建达梦数据库
  7. 低延时互动直播双十一优惠活动
  8. pymongo使用经验
  9. 子界类型(Subrange types)
  10. 产品读书《定位:有史以来对美国营销影响最大的观念》
  11. 如何做一个简单的学生喜欢家长买单的scratch小游戏
  12. 非支配快速排序算法详解
  13. adaway的jni设计摸索
  14. STM32调试过程 常见错误及解决方案
  15. 又一大的技术站点域名被ClientHold了
  16. win10禁用操作系统的服务器,win10服务哪些可以禁止启动 win10哪些服务可以关闭禁用...
  17. ubuntu安装和使用labellmg(含pyqt4的安装教程)
  18. 解决浏览器连不上校园网问题
  19. STM32103驱动28BYJ48步进电机
  20. GoogleNet、AleXNet、VGGNet、ResNet等总结

热门文章

  1. 《FlaskWeb开发:基于Python的Web应用开发实战》笔记
  2. 汇编语言 LOOP和[BX]的联合应用
  3. php如何获取ajax请求,php-从ajax调用获取json数据
  4. mysql重新载入my.cnf_怎么重新加载MySQL的my.cnf?
  5. Spring学习-- SpEL表达式
  6. 记一次 @Transactional不生效的问题
  7. JAXB 有两个名为 ** 的属性,类的两个属性具有相同名称 **解决方案
  8. leetcode -- 357. Count Numbers with Unique Digits
  9. 洛谷——P1071 潜伏者
  10. 未公开接口主要指以下哪几类_Java8的 Stream 函数式接口,你了解多少?