java位原子_Java原子操作AtomicInteger的用法
前言:
JDK1.5之后的java.util.concurrent.atomic包里,多了一批原子处理类。AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference。主要用于在高并发环境下的高效程序处理,来帮助我们简化同步处理.
AtomicInteger:
AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。
我们先来看看AtomicInteger给我们提供了什么接口:
public final int get() //获取当前的值
public final int getAndSet(int newValue)//获取当前的值,并设置新的值
public final int getAndIncrement()//获取当前的值,并自增
public final int getAndDecrement() //获取当前的值,并自减
public final int getAndAdd(int delta) //获取当前的值,并加上预期的值
下面通过两个简单的例子来看一下 AtomicInteger 的优势在哪:
普通线程同步:
class Test2 {
private volatile int count = 0;
public synchronized void increment() {
count++; //若要线程安全执行执行count++,需要加锁
}
public int getCount() {
return count;
}
}
使用AtomicInteger:
class Test2 {
private AtomicInteger count = new AtomicInteger();
public void increment() {
count.incrementAndGet();
}
//使用AtomicInteger之后,不需要加锁,也可以实现线程安全。
public int getCount() {
return count.get();
}
}
从上面的例子中我们可以看出:使用AtomicInteger是非常的安全的.而且因为AtomicInteger由硬件提供原子操作指令实现的。在非激烈竞争的情况下,开销更小,速度更快。
我们来看看AtomicInteger是如何使用非阻塞算法来实现并发控制的:
AtomicInteger的关键域只有一下3个:
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
private volatile int value;
这里, unsafe是java提供的获得对对象内存地址访问的类,注释已经清楚的写出了,它的作用就是在更新操作时提供“比较并替换”的作用。实际上就是AtomicInteger中的一个工具。
valueOffset是用来记录value本身在内存的便宜地址的,这个记录,也主要是为了在更新操作在内存中找到value的位置,方便比较。
注意:value是用来存储整数的时间变量,这里被声明为volatile,就是为了保证在更新操作时,当前线程可以拿到value最新的值(并发环境下,value可能已经被其他线程更新了)。
这里,我们以自增的代码为例,可以看到这个并发控制的核心算法:
/**
*Atomicallyincrementsbyonethecurrentvalue.
*
*@returntheupdatedvalue
*/
publicfinalintincrementAndGet(){
for(;;){
//这里可以拿到value的最新值
intcurrent=get();
intnext=current+1;
if(compareAndSet(current,next))
returnnext;
}
}
publicfinalbooleancompareAndSet(intexpect,intupdate){
//使用unsafe的native方法,实现高效的硬件级别CAS
returnunsafe.compareAndSwapInt(this,valueOffset,expect,update);
}
优点总结:
最大的好处就是可以避免多线程的优先级倒置和死锁情况的发生,提升在高并发处理下的性能。
java位原子_Java原子操作AtomicInteger的用法相关推荐
- java 位掩码_Java位掩码控制权限与()或(|)非(~)、的介绍
1. java 位掩码 java 位掩码,在java开发中很少有场景会用到掩码,但是当系统中需要判断某个对象是否有 某些权限时,可以通过位掩码来做. 位掩码 主要通过位运算,例如与(&).非( ...
- java volatile实例_Java的Volatile实例用法及讲解
Java的Volatile实例用法及讲解 发布时间:2020-10-03 12:01:58 来源:脚本之家 阅读:88 作者:konami 在原子性.可见性.有序性中,volatile关键字主要在可见 ...
- java synchronized 使用_Java中Synchronized的用法
synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码 ...
- java synchronized静态_Java中Synchronized的用法(简单介绍)
简单介绍 synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调 ...
- java位宽_Java的数据类型
Java数据类型 Java虚拟机是通过某些数据类型来执行计算的,数据类型及其运算都是由Java虚拟机规范严格定义的. 数据类型分为两种:基本数据类型和引用数据类型.基本类型的变量持有原始值,而引用数据 ...
- java 位运算_java学习之运算符与表达式(四)
(6)位运算符 位运算是指对整数按二进制的位进行运算. 位运算用于整数或字符类型. 有7个:~(非).&(与).|(或).^(异或).<>(右移).>>>(无符号 ...
- java位宽_java数据类型
┏数值型━┳━整数型:byte short int long ┏基本数据类型━━┫ ┗━浮点型:float double ┃ ...
- java printwriter实例_Java PrintWriter print(String)用法及代码示例
Java中的PrintWriter类的print(String)方法用于在流上打印指定的String值.该字符串值用作参数. 用法: public void print(String StringVa ...
- java 匿名内部类 参数_Java匿名内部类原理与用法详解
本文实例讲述了Java匿名内部类原理与用法.分享给大家供大家参考,具体如下: 一 点睛 匿名内部类适合创建那种只需要一次使用的类,定义匿名内部类的语法格式如下: new 父类构造器(实参列表) | 实 ...
- java jad怎么_JAVA反编译 jad用法
JAVA反编译 jad用法 Java下的一个简单易用的反编译工具jad , 可以很方便的将.class反编译为.Java. 一.基本用法 Usage:jad [option(s)] 直接输入类文件名, ...
最新文章
- SQL 全角半角转换-(摘抄)
- Android性能优化之电量篇(四)
- python获取今年第一天_利用python获取某年中每个月的第一天和最后一天
- oracle客户端没有装exp,oracle 10G 客户端安装后,尝试 exp 命令报错, 求解
- redis所有版本下载地址
- HBuilder 打包流程
- T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他(看了两次了,转了)
- 有关Silverlight TabControl组件的研究——Silverlight学习笔记(5)
- c语言全面,最新版c语言经典习题100例(最全面).doc
- linux内核循环,循环缓冲区(参考linux内核Kfifo)
- 单片机程序的整体框架设计的一些思路体会
- 如何看待国内开源现状?贾扬清、李沐、陈天奇等大牛如是说
- 1024我的Java上车日记(二)
- 家庭用计算机音响,7.1声道THX家庭影院音箱摆位计算器
- 在 Linux中 cp复制文件时,出现略过的提示
- 搭建fastdfs服务,及单机redis服务,springboot实现h5与fastdfs之间的断点续传,大文件上传,秒传文件和批量上传
- 29岁华为员工工资曝光,揭露残酷真相:职场下半场,拼的就是这项能力!
- golang——gorountine+channal
- 前度字符串转数组_关于前度书籍的阿里云论坛用户知识和技术交流
- php文件目录教程,详谈PHP文件目录基础操作_PHP教程
热门文章
- python bootstrap 中位数_【机器学习】Bootstrap详解
- ubuntu 如何确定虚拟机中的网关_如何在虚拟机中安装Kali Linux
- oracle中同义词总结,ORACLE同义词总结
- python多维数据聚类可视化_基于python3的可视化数据聚类系统(k-means算法和k-中心点算法)...
- Android播放c4d工程文件方法,安卓播放网络视频怎么实现?
- lib文件夹 springboot_我把 Spring Boot 项目从 18.18M 瘦身到 0.18M,部署起来真省事!...
- 数据库—事务—并发控制技术
- 回发或回调参数无效。在配置中使用 或在页面中使用 启用了事件验证....
- oracle 创建表同时添加注释
- 【转】Ubuntu 16.04安装配置TensorFlow GPU版本