首页 > 编程语言 >【Java 并发】【八】【Atomic】【一】JUC下的Atomic原子类体系概览

【Java 并发】【八】【Atomic】【一】JUC下的Atomic原子类体系概览

时间:2023-04-03 22:23:11浏览次数:42  
标签:JUC Java 原子 并发 线程 Atomic AtomicLong AtomicBoolean

1  前言

这节我们就开始看看Atomic原子类系列,JUC包下提供的原子类底层的实现原理基本都是差不多的,都是基于volatile和CAS操作来保证线程安全的,我们后续会着重分析几个类。

2  概览

我们看下JUC下边都有哪些原子类:

看上面的图形,我们使用红色圈中的那些,就是我们要着重讨论的,一共分为一下几个类别:

(1)AtomicInteger、AtomicLong整型的原子类

如果我们在程序中使用了基本的Integer、Long等类型,进行基本的数学加减运算、赋值操作等。但是如果是在多线程环境下多个线程同时操作同一个Integer、Long变量,可能导致线程安全的问题。

要规避线程安全的问题,你可能需要用到锁,比如常用的synchronized、ReentrantLock锁等,让同一时间只有一个线程操作变量;但是锁是一个比较重的操作,可能导致线程获取不到锁而陷入沉睡,这样就会导致并发的性能降低。

然而如果你需要很高的并发性能,不想用锁,但需要是线程安全的;在这种情况下JUC就为我们提供了线程安全的原子类AtomicInteger、AtomicLong等,在多线程环境下进行加减运算、赋值操作等都是线程安全的。

AtomicInteger、AtomicLong使用非常广泛,比如你的系统里面可能用到一些统计、计数场景,比如每秒访问的流量、注册中心每秒接收到注册的次数、心跳的次数、可以使用这两个原子类。

在一些开源的分布式系统、中间件系统里面,大量的metric指标统计的功能都是基于AtomicInteger、AtomicLong这两个原子类去实现的,非常重要。

(2)AtomicBoolean 布尔类型的原子类

在多线程环境下我们使用基本的boolean、Boolean类型的布尔变量是非线程安全的,JUC提供类线程安全的布尔类型原子类AtomicBoolean。

AtmoicBoolean 通常使用的场景是一些状态标识,比如初始化标识、系统关闭标识、逻辑状态判断标识、状态开关等等。

此外AtomicBoolean 还经常使用做非常轻量级的锁,比如阿里开源的分布式消息中间件RocketMQ就使用了AtomicBoolean封装了一个自旋锁,具有非常高的并发性能。(CAS将AtomicBoolean设置成true表示获取到了锁,释放锁的时候CAS操作将AtomicBoolean设置为false)

(3)AtomicReference、AtomicStampReference可以封装对象的原子类

上面的提供的AtomicInteger、AtomicLong、AtomicBoolean等都是基本类型对应的原子类;但是如果你共享的是一个对象呢?多个线程同时修改一个对象呢?

在不使用锁的场景下可以将对象使用AtomicReference进行包装,然后CAS的去修改对象,也可以达到线程安全的效果。

AtomicStampReference 则是AtomicReference的升级版本,提供版本号机制,解决CAS中经典的ABA问题

(4)LongAdder原子类

是AtomicLong原子类的一个升级版本,在并发竞争非常激烈的时候可能会导致大量的线程CAS失败而不断自旋。

LongAdder采用分段锁的思想,在并发竞争非常激烈的时候使得不同的线程去竞争不同的锁;这样就可以减少对同一个锁的竞争,优化了并发的性能。

3  小结

这节我们大概看下原子类有哪些,以及我们接下来主要研究的几个,有理解不对的地方欢迎指正哈。

标签:JUC,Java,原子,并发,线程,Atomic,AtomicLong,AtomicBoolean
From: https://www.cnblogs.com/kukuxjx/p/17284628.html

相关文章

  • Java-Day-3(运算符 + 标识符 + 键盘输入)
    Java-Day-3运算符算术运算符关系运算符[比较运算符]逻辑运算符赋值运算符三元运算符位运算符[需要二进制基础]算术运算符+、-、*、/System.out.println(10.0/4);//2.5doubled=10/4;//2.0//数学公式有时不能硬搬,例如:摄氏温度=5/9*(华氏温......
  • 1006-HBase操作实战(JAVA API模式)
    一、准备阶段开发环境:hadoop: hadoop -2.4.0hbase: hbase -0.94.11-securityeclipse:JunoServiceRelease2二、创建 hbasedemo项目1、通过Eclipse创建一个新Java工程2、右击项目根目录,选择“Propertiesà>JavaBuildPathà>Libraryà> Add Ext......
  • 如何使用Java程序实现二叉数
    二叉树是一种重要的数据结构,它由一组节点组成,每个节点可以拥有最多两个子节点。使用Java可以很容易地实现一个二叉树。下面将介绍如何使用Java实现二叉树。二叉树的节点定义一个二叉树的节点可以定义为一个类,其中至少需要包含以下属性:节点值左子节点右子节点在Java中,我们......
  • Java多线程
    1.可见性、原子性和有序性问题多线程有三大特性,分别是可见性、原子性和有序性。1.1可见性  在单核时代,所有的线程都是在一颗CPU上执行,CPU缓存与内存的数据一致性容易解决。因为所有线程都是操作同一个CPU的缓存,一个线程对缓存的写,对另外一个线程来说一定是可见的。一个线程......
  • Java判断文件夹、文件是否存在,不存在则新建
    Java判断文件夹、文件是否存在,不存在则新建原文链接:https://blog.csdn.net/asfsdgdfgdf/article/details/1283162781、Java判断是否存在文件夹,不存在则新建Filefile=newFile("D:/test/filetest/test.txt");if(!file.getParentFile().exists()){file.getParentFile().......
  • Java 获取当前或调用者类名和方法名(Thread.currentThread().getStackTrace()、new Thr
    Java获取当前或调用者类名和方法名(Thread.currentThread().getStackTrace()、newThrowable().getStackTrace())原文链接:https://blog.csdn.net/inthat/article/details/111885544文章目录一、Java获取当前类名和方法名Thread.currentThread().getStackTrace()1.关于Thr......
  • 2-Java基础语法
    1.注释注释是对代码的解释和说明文字。Java中的注释分为三种:单行注释://这是单行注释文字多行注释:/_这是多行注释文字这是多行注释文字这是多行注释文字_/注意:多行注释不能嵌套使用。文档注释(暂时用不到):/*_这是多行注释文字这是多行注释文字这是多......
  • 如何用Java程序生成大乐透号码?
    在大乐透游戏中,需要选出5个红球号码和2个蓝球号码。这个过程可能比较耗时,而且如果想要生成多组号码,手动输入的方式就变得特别不切实际。因此,我们可以使用Java程序来实现大乐透号码的自动生成。一、生成红球号码首先,需要确定生成红球号码的范围和数量。在大乐透游戏中,红球号码的......
  • 关闭Java时后台的FM无法恢复
    在MVM的版本中,先启动任何本地播放音乐的应用FM/Audioplayer,此时同时启动多个没有音乐的Java应用,并关闭某一个Java应用,之前后台的FM等无法重新恢复播放。例如: 1、启动FM->启动Java应用A,FM停止播放->后台A->FM恢复->启动Java应用B,FM停止播放->后台......
  • JAVA列表中屏蔽预置程序
    1.Jam_interface.h中添加FilterType。 typedefenum{JAM_NONE_FILTER=0,JAM_DISK_FILTER=0x01,JAM_TRUST_FILTER=0x02,JAM_VENDOR_FILTER=0x04,JAM_DEFAULT_GAME_FILTER=0x08,JAM_NONDEFAULT_GAME_FILTER=......