java多线程系列5 atomic简介
先看一个例子,AtomicInteger 实现的线程安全的累加器
public class AtomicIntTest {
public static void main(String[] args) {
AddRunnable addRunnable = new AddRunnable();
Thread myThread1 = new Thread(addRunnable);
Thread myThread2 = new Thread(addRunnable);
myThread1.start();
myThread2.start();
try {
myThread1.join();
myThread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(addRunnable.count);
}
}
class AddRunnable implements Runnable {
AtomicInteger count = new AtomicInteger();
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
count.incrementAndGet();
}
}
}
AtomicInteger源码分析
下面通过AtomicInteger的源码来看一下是怎么在没有锁的情况下保证数据正确性。首先看一下incrementAndGet方法的实现
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
注意::valueOffset叫做 偏移量 我们知道valueOffset指向的地址对应的值就是原始变量的值 执行逻辑就是 expect 和valueOffset 比较 相同 就替换成 update 不同继续循环
总结:
1 虽然基于CAS的线程安全机制很好很高效,但要说的是,并非所有线程安全都可以用这样的方法来实现,这只适合一些粒度比较小,型如计数器这样的需求用起来才有效,否则也不会有锁的存在了。实际来发中,用锁的情况还是较多。
2 并发越高,失败的次数会越多,CAS如果长时间不成功,会极大的增加CPU的开销。(毕竟死循环嘛) 因此CAS不适合竞争十分频繁的场景。
3 CAS只能保证一个共享变量的原子操作。当对多个共享变量操作时,CAS就无法保证操作的原子性,这时就可以用锁,或者把多个共享变量合并成一个共享变量来操作。使用AtomicReference。
java多线程系列5 atomic简介的更多相关文章
- Java多线程系列——线程池简介
什么是线程池? 为了避免系统频繁地创建和销毁线程,我们可以让创建的线程进行复用.用线程时从线程池中获取,用完以后不销毁线程,而是归还给线程池. JDK 对线程池的支持 为了更好的控制多线程,JDK 提 ...
- Java多线程系列九——Atomic类
参考资料:https://fangjian0423.github.io/2016/03/16/java-AtomicInteger-analysis/http://www.cnblogs.com/54 ...
- java多线程系列 目录
Java多线程系列1 线程创建以及状态切换 Java多线程系列2 线程常见方法介绍 Java多线程系列3 synchronized 关键词 Java多线程系列4 线程交互(wait和 ...
- Java多线程系列——从菜鸟到入门
持续更新系列. 参考自Java多线程系列目录(共43篇).<Java并发编程实战>.<实战Java高并发程序设计>.<Java并发编程的艺术>. 基础 Java多线 ...
- java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析
java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...
- Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例
概要 前面对"独占锁"和"共享锁"有了个大致的了解:本章,我们对CountDownLatch进行学习.和ReadWriteLock.ReadLock一样,Cou ...
- Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例
概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
随机推荐
- Android入门(一) IDEA上创建Android应用之helloworld
Android入门(一) IDEA上创建Android应用之helloworld 首先看运行结果: 一.准备工作 下载安装IntelliJ IDEA :我这里用的是2018.2.7 下载安装Genym ...
- django 多线程下载图片
example1: from multiprocessing.dummy import Pool as ThreadPool #多线程 import time import urllib2 urls ...
- jquery:获取checked复选框的问题
jquery:获取checked复选框的问题 功能描述:要完成一个全选的功能,但总是获取不到复选框的被选中的个数,究其原因,是Jquery中length和checked使用不当所造成的. // 获取所 ...
- linux服务之apache篇(一)
1.apache介绍:使用率最高的网站服务器: URL:统一资源定位符: 端口:http:80 https:443 2.apache三种工作模式: prefork:一个线程处理一个请求(占用内存多 ...
- ORA-03137: TTC 协议内部错误: [12333] [4] [49] [51] [] [] [] []
[1]问题背景:Oracle数据库版本为11.2.0.1,操作系统CentOS release 5.9,详细的报错信息如下: Dump file /data/oracle/diag/rdbms/db0 ...
- python3笔记<二> List
python数组申明用方括号:例: Arr = ['python','java','javascript'] 截取其中一段元素:例: Arr = [5,6,7,8,9,10,11,12,13,14,1 ...
- Android 开发 HandlerThread详解 转载
转载请注明出处:http://blog.csdn.net/vnanyesheshou/article/details/75073307 对于Handler不太懂的可以参考我的这两篇文章: Androi ...
- nginx ------反向代理和负载均衡
最近由于公司的业务增长 服务器承受不住压力经常出现崩溃现象 为了解决 使用nginx的负载均衡解决,以下是操作步骤: 1.nginx 的负载均衡:将压力分散到不同的机器上 nginx不单可以作为强大的 ...
- java数据类型关系及关系
java中有常见的基本数据类型和引用数据类型,基本数据类型为四类八种如下 整数型(byte,short,int,long) 浮点型(float,double) 字符型(char) 布尔型(boolea ...
- Redis内存模型总结
一.Redis内存统计 在客户端通过redis-cli连接服务器后,通过info命令可以查看内存使用情况: info memory 返回结果中比较重要的几个说明如下: (1)used_memory:R ...