java并发:原子类之AtomicLong
原子类之AtomicLong
java线程中的操作,需要满足原子性、可见性等原则,比如i++这样的操作不具备原子性,
A线程读取了i,另一个线程执行i++,A线程再执行i++就会引发线程安全问题
推荐学习的AtomicInteger和AtomicLong博客
你还在用Synchronized?Atomic你了解不?
Java多线程系列--“JUC原子类”02之 AtomicLong原子类
一个非原子性的自加引发的安全例子
下面的例子执行1000个线程,有意思的还Long自加比Interger更容易发现结果是比1000小。
package com.java.javabase.thread.base.concurrent.atomic;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Slf4j
public class AtomicLongtest {
public static void main(String[] args) {
AtomicLongtest test =new AtomicLongtest();
Count count =test.new Count();
ExecutorService service = Executors.newCachedThreadPool();
for(int i=0;i<1000;i++){
service.execute(()->count.increace());
}
service.shutdown();
try {
service.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("End count :{}",count.getCount());
}
@Data
class Count{
private Long count=0L;
public void increace(){
log.info("count {}",count++);
}
}
}
通过syncronized方法
通过syncronized方法使得自加操作安全
使用AtomicLong满足原子性
使用AtomicLong满足原子性主要是实现了CAS
比较并交换(compare and swap, CAS),是原子操作的一种,可用于在多线程编程中实现不被打断的数据交换操作,从而避免多线程同时改写某一数据时由于执行顺序不确定性以及中断的不可预知性产生的数据不一致问题。 该操作通过将内存中的值与指定数据进行比较,当数值一样时将内存中的数据替换为新的值。
使用使用AtomicLong,1000个线程执行之后返回的结果是1000,保证了结果的正确
package com.java.javabase.thread.base.concurrent.atomic;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
@Slf4j
public class AtomicLongTest2 {
public static void main(String[] args) {
AtomicLongTest2 test =new AtomicLongTest2();
Count count =test.new Count();
ExecutorService service = Executors.newCachedThreadPool();
for(int i=0;i<1000;i++){
service.execute(()->count.increace());
}
service.shutdown();
try {
service.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("End count :{}",count.getCount());
}
@Data
class Count{
private AtomicLong count=new AtomicLong(0);
public void increace(){
log.info("count {}",count.incrementAndGet());
}
}
}
AtomicLong的ABA问题
CAS有一个问题是ABA问题:
1.ABC三个线程
2.count=10,这时AB线程的内存值和预期值都是10
3.B线程把count修改100成功后,内存值是100
4.A线程又把count设置为10
5.这个时候内存值和预期值都是10
6.c线程是不知道A和B对count做了什么操作的
java并发:原子类之AtomicLong的更多相关文章
- Java并发—原子类,java.util.concurrent.atomic包(转载)
原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...
- java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4
java 线程 原子类相关操作演示样例 package org.rui.thread.volatiles; import java.util.Timer; import java.util.Time ...
- java核心-多线程(8)- 并发原子类
使用锁能解决并发时线程安全性,但锁的代价比较大,而且降低性能.有些时候可以使用原子类(juc-atomic包中的原子类).还有一些其他的非加锁式并发处理方式,我写这篇文章来源于Java中有哪些 ...
- java的原子类到底是啥?ABA,CAS又是些什么?
1)解决并发不是用锁就能解决吗,那SDK干嘛还要搞个原子类出来? 锁虽然能解决,但是加锁解锁始终还是对性能是有影响的,并且使用不当可能会造成死锁之类的问题. 2)原子类是怎样使用的,比如说我要实现一个 ...
- (转)Java atomic原子类的使用方法和原理(一)
在讲atomic原子类之前先看一个小例子: public class UseAtomic { public static void main(String[] args) { AtomicIntege ...
- java的原子类 AtomicInteger 实现原理是什么?
采用硬件提供原子操作指令实现的,即CAS.每次调用都会先判断预期的值是否符合,才进行写操作,保证数据安全. CAS机制 CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换. ...
- Java - “JUC”原子类
根据修改的数据类型,可以将JUC包中的原子操作类可以分为4类. 1. 基本类型: AtomicInteger, AtomicLong, AtomicBoolean ;2. 数组类型: AtomicIn ...
- java并发编程-12个原子类
背景 多线程更新变量的值,可能得不到预期的值,当然增加syncronized关键字可以解决线程并发的问题. 这里提供另外一种解决问题的方案,即位于 java.util.concurrent.atomi ...
- 【Java并发工具类】原子类
前言 为保证计数器中count=+1的原子性,我们在前面使用的都是synchronized互斥锁方案,加锁独占访问的方式未免太过霸道,于是我们来介绍另一种解决原子性问题的无锁方案:原子变量.在正式介绍 ...
随机推荐
- python二维数组的创建
话不多说,代码伺候 m = [[]*]*3 #创建一个3行5列的二维数组 m[][]= print(m) 输出结果为: 分析: m = [[0]*5]*3只是指向三个空列表的引用. 创建一个二维数组的 ...
- 数码管显示“0~F”的共阳共阴数码管编码表
嵌入式设备中数码管显示“0~F”的方式是:定义了一个数组,里面含有16个元素,分别代表0~F,这样可以方便以后的调用.共阳极数码管编码表:unsigned char table[]={0xc0,0xf ...
- laravel 语言包拓展
laravel 使用make:auth生成用户认证,登录表单是英文版本的,打开模板文件(resources/views/auth/login.blade.php),此模板文件是我们刚刚使用 make: ...
- 13. 为什么我们会需要 Pod?
13. 为什么我们会需要 Pod? 13.1 docker容器的本质 """ docker容器的本质 是进程. 主要通过 Namespace 做隔离,Cgroups 做限 ...
- CSS水平垂直居中常见方法总结
1.元素水平居中 当然最好使的是: margin: 0 auto; 居中不好使的原因: 1.元素没有设置宽度,没有宽度怎么居中嘛! 2.设置了宽度依然不好使,你设置的是行内元素吧,行内元素和块元素的区 ...
- 吴裕雄 python 神经网络——TensorFlow 数据集高层操作
import tempfile import tensorflow as tf train_files = tf.train.match_filenames_once("E:\\output ...
- kafka connector
Kafka Connect 是一种用于在 Kafka 和其他系统之间可扩展的.可靠的的流式传输数据的工具.它使得能偶快速定义将大量数据集合移入和移除 kafka 连接器变得简单. kafka conn ...
- 【转】网关协议学习:CGI、FastCGI、WSGI、uWSGI
一直对这四者的概念和区别很模糊,现在就特意梳理一下它们的关系与区别. CGI CGI即通用网关接口(Common Gateway Interface),是外部应用程序(CGI程序)与Web服务器之间的 ...
- 「CF1313C Skyscrapers」
题目大意 给出一个长度为 \(N\) 的序列 \(a\) 需要构造出一个长度为 \(N\) 的序列 \(h\) 使得 \(\forall i \in \{1,2,\ldots ,N\} h_i \le ...
- IIS 配置迁移
使用管理员身份运行cmd 应用程序池: # 导出所有应用程序池 %windir%\system32\inetsrv\appcmd list apppool /config /xml > c:\a ...