原子类之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的更多相关文章

  1. Java并发—原子类,java.util.concurrent.atomic包(转载)

    原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...

  2. java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4

    java 线程  原子类相关操作演示样例 package org.rui.thread.volatiles; import java.util.Timer; import java.util.Time ...

  3. java核心-多线程(8)- 并发原子类

        使用锁能解决并发时线程安全性,但锁的代价比较大,而且降低性能.有些时候可以使用原子类(juc-atomic包中的原子类).还有一些其他的非加锁式并发处理方式,我写这篇文章来源于Java中有哪些 ...

  4. java的原子类到底是啥?ABA,CAS又是些什么?

    1)解决并发不是用锁就能解决吗,那SDK干嘛还要搞个原子类出来? 锁虽然能解决,但是加锁解锁始终还是对性能是有影响的,并且使用不当可能会造成死锁之类的问题. 2)原子类是怎样使用的,比如说我要实现一个 ...

  5. (转)Java atomic原子类的使用方法和原理(一)

    在讲atomic原子类之前先看一个小例子: public class UseAtomic { public static void main(String[] args) { AtomicIntege ...

  6. java的原子类 AtomicInteger 实现原理是什么?

    采用硬件提供原子操作指令实现的,即CAS.每次调用都会先判断预期的值是否符合,才进行写操作,保证数据安全. CAS机制 CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换. ...

  7. Java - “JUC”原子类

    根据修改的数据类型,可以将JUC包中的原子操作类可以分为4类. 1. 基本类型: AtomicInteger, AtomicLong, AtomicBoolean ;2. 数组类型: AtomicIn ...

  8. java并发编程-12个原子类

    背景 多线程更新变量的值,可能得不到预期的值,当然增加syncronized关键字可以解决线程并发的问题. 这里提供另外一种解决问题的方案,即位于 java.util.concurrent.atomi ...

  9. 【Java并发工具类】原子类

    前言 为保证计数器中count=+1的原子性,我们在前面使用的都是synchronized互斥锁方案,加锁独占访问的方式未免太过霸道,于是我们来介绍另一种解决原子性问题的无锁方案:原子变量.在正式介绍 ...

随机推荐

  1. eclipse配置tomcat后修改server.xml文件(如编码等)无效问题

    我们用eclipse配置好tomcat后,在处理中文乱码或是配置数据源时,我们要修改Tomcat下的server.xml等文件. 修改后重启Tomcat服务器时发现xml文件又被还原了. 因为Tomc ...

  2. Manjaro 安装 ibus-rime 输入法

    Manjaro 安装 ibus-rime 输入法 安装软件包: sudo pacman -S ibus ibus-rime yay -S ibus-qt 编辑/添加配置文件~/.xprofile: e ...

  3. Unity中调用Windows窗口选择文件

    1.OpenFileName数据接收类,如下: using UnityEngine; using System.Collections; using System; using System.Runt ...

  4. IPSec的链路和设备备份

    链路备份的IPSec VPN和设备备份的IPSec VPN:首先实验的是链路备份的  IPSec VPN,下面是实验拓扑: IP地址配置:R1(Branch):Branch(config-if)#ip ...

  5. MySQL优化2.索引

    什么是索引: 索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容. 建立索引合适的列 经常用作where条件的列,order by排序的列 数据列不重复而且并不是唯一的几个值 不被经常 ...

  6. 动态规划-爬楼梯问题java实现

    最近开始看算法导论,研究了一下动态规划,下面就开始直入主题开始记录近期看的第一个知识点动态规划.提起动态规划就不得不提几个动态规划的金典问题爬楼梯.国王金矿.背包问题.今天就仔细分析一下爬楼梯问题. ...

  7. [03] Recursive Function递归应用

    递归应用 1.理解 百科:一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的: 理解:函数调用自己的过程,这类函数处理的事情具有重复性,处理此类实行可用while或者for,但结构上 ...

  8. c#活动目录操作

    c#活动目录操作  https://www.cnblogs.com/ahuo/archive/2007/03/16/676853.html 添加引用 System.DirectoryServices导 ...

  9. 嵌入式实时程序设计中C/C++代码的优化

    1 引言 计算机技术和信息技术的高速发展的今天,计算机和计算机技术大量应用在人们的日常生活中,嵌入式计算机也得到了广泛的应用.嵌入式计算机是指完成一种或多种特定功能的计算机系统,是软硬件的紧密结合体. ...

  10. Dart语言学习(十五) Dart函数方法

    Dart函数方法可分为两类: 一.内置方法/函数: print(); 二.自定义方法: 自定义方法的基本格式: 返回类型 方法名称(参数1,参数2,...){ 方法体 return 返回值; } vo ...