(转)Java atomic原子类的使用方法和原理(一)
在讲atomic原子类之前先看一个小例子:
public class UseAtomic {
public static void main(String[] args) {
AtomicInteger atomicInteger=new AtomicInteger();
for(int i=0;i<10;i++){
Thread t=new Thread(new AtomicTest(atomicInteger));
t.start();
try {
t.join(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(atomicInteger.get());
}
}
class AtomicTest implements Runnable{
AtomicInteger atomicInteger;
public AtomicTest(AtomicInteger atomicInteger){
this.atomicInteger=atomicInteger;
}
@Override
public void run() {
atomicInteger.addAndGet(1);
atomicInteger.addAndGet(2);
atomicInteger.addAndGet(3);
atomicInteger.addAndGet(4);
}
}
最终的输出结果为100,可见这个程序是线程安全的。如果把AtomicInteger换成变量i的话,那最终结果就不确定了。
打开AtomicInteger的源码可以看到:
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private volatile int value;
volatile关键字用来保证内存的可见性(但不能保证线程安全性),线程读的时候直接去主内存读,写操作完成的时候立即把数据刷新到主内存当中。
CAS简要
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
从注释就可以看出:当线程写数据的时候,先对内存中要操作的数据保留一份旧值,真正写的时候,比较当前的值是否和旧值相同,如果相同,则进行写操作。如果不同,说明在此期间值已经被修改过,则重新尝试。
compareAndSet使用Unsafe调用native本地方法CAS(CompareAndSet)递增数值。
CAS利用CPU调用底层指令实现。
两种方式:总线加锁或者缓存加锁保证原子性。
作者:zxin1
链接:https://www.jianshu.com/p/a2f3c46d4783
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
(转)Java atomic原子类的使用方法和原理(一)的更多相关文章
- Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。
精彩理解: https://www.jianshu.com/p/21be831e851e ; https://blog.csdn.net/heyutao007/article/details/19 ...
- Java线程--Atomic原子类使用
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871241.html Java线程--Atomic原子类使用 package concurr ...
- JUC 中的 Atomic 原子类总结
1 Atomic 原子类介绍 Atomic 翻译成中文是原子的意思.在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的.在我们这里 Atomic 是指一个操作是不可中断的.即使是 ...
- Atomic原子类
Atomic原子类 Atomic原子类位于并发包java.util.concurrent下的java.util.concurrent.Atomic中. 1. 原子更新基本类型类 使用原子方式更新基本数 ...
- java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4
java 线程 原子类相关操作演示样例 package org.rui.thread.volatiles; import java.util.Timer; import java.util.Time ...
- Juc中Atomic原子类总结
1 Atomic原子类介绍 2 基本类型原子类 3 数组类型原子类 4 引用类型原子类 5 对象的属性修改类型原子类
- 并发编程学习笔记(4)----jdk5中提供的原子类及Lock使用及原理
(1)jdk中原子类的使用: jdk5中提供了很多原子类,它会使变量的操作变成原子性的. 原子性:原子性指的是一个操作是不可中断的,即使是在多个线程一起操作的情况下,一个操作一旦开始,就不会被其他线程 ...
- [Java多线程]-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- Java并发—原子类,java.util.concurrent.atomic包(转载)
原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...
随机推荐
- Expm 2_2 查找中项问题
对于长度为n的整型数组A,随机生成其数组元素值,然后实现一个线性时间的算法,在该数组中查找其中项. package org.xiu68.exp.exp3; import java.util.Array ...
- 请手动释放你的资源(Please release resources manually)
作者: Laruence( ) 本文地址: http://www.laruence.com/2012/07/25/2662.html 转载请注明出处 我从来不认为这个问题是个问题, 直到昨天. 昨 ...
- vue-router之路由钩子(组件内路由钩子必须在路由组件调用,子组件没用)
模式 vue-router中的模式选项主要在router实例化的时候进行定义的,如下 const router = new VueRouter({ mode: 'history', // 两种类型hi ...
- 关于Newtonsoft.Json,反序列化jason,内容有key的转换
Newtonsoft.Json,反序列化,对于result里面的结果,可以使用Dictionary<string, List<类名>>,string是key值,value又是一 ...
- 并发研究之Java内存模型(Java Memory Model)
Java内存模型JMM java内存模型定义 上一遍文章我们讲到了CPU缓存一致性以及内存屏障问题.那么Java作为一个跨平台的语言,它的实现要面对不同的底层硬件系统,设计一个中间层模型来屏蔽底层的硬 ...
- 把linux文件夹压缩成tar.gz的命令
解压 tar zxvf 文件名.tar.gz 压缩 tar zcvf software.tar.gz /usr/local/software
- java中final,finally,finalize三个关键字的区别
final 可以作为修饰符修饰变量.方法和类. 被final修饰的变量必须在初始化时给定初值,以后在使用时只能被引用而不能被修改. 被final修饰的方法不能够在子类中被重写(override): 被 ...
- Python yaml处理
安装方式: pip install pyyaml 一.module.yaml为 name: Tom Smith age: 37 spouse: name: Jane Smith age: 25 chi ...
- IE浏览器url中带中文报错的问题;以及各种兼容以及浏览器问题总结
1.解决IE浏览器url带中文报错 /* encodeURI()解决IE浏览器请求url中带中文报错的问题 */ URL = encodeURI("<%=basePath%>ve ...
- Python - 常用更新命令以及常见库安装
库的安装方式一般有两种: 一. pip直接安装(或使用豆瓣源) pip install scrapy pip install -i https://pypi.douban.com/simple/ sc ...