首页 > 编程语言 >JUC并发编程学习笔记(十九)原子引用

JUC并发编程学习笔记(十九)原子引用

时间:2023-11-14 19:34:22浏览次数:32  
标签:JUC 版本号 编程 System stamp atomic println 十九 out

原子引用

带版本号的原子操作!

解决ABA问题,引入原子引用(乐观锁思想)

AtomicStampedReference类解决ABA问题

package org.example.cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

//使用原子引用解决ABA问题
public class ABADemo {
    public static void main(String[] args) {
        //默认值 默认版本号(时间戳)
        //如果泛型是一个包装类,注意对象引用的问题
        //正常在业务中里面比较并交换的一般是一个个对象如User这种
        AtomicStampedReference<Integer> atomic = new AtomicStampedReference<>(1,1);
        new Thread(()->{
            int stamp = atomic.getStamp();//获得版本号
            System.out.println("a1版本号=》"+stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //atomic.compareAndSet 期待的值 更新的值 期待的版本号 更新的版本号
            //当期待的值和期待的版本号都满足期待时,就更新值和版本号
            System.out.println(atomic.compareAndSet(1, 2, stamp, stamp + 1));
            System.out.println("a2版本号=》"+atomic.getStamp());
            System.out.println(atomic.compareAndSet(2, 1, atomic.getStamp(), atomic.getStamp() + 1));
            System.out.println("a3版本号=》"+atomic.getStamp());
        },"A").start();
        //与乐观锁原理相同
        new Thread(()->{
            int stamp = atomic.getStamp();//获得版本号
            System.out.println("b1版本号=》"+stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(atomic.compareAndSet(1, 2, stamp, stamp + 1));
            System.out.println("b2版本号=》"+atomic.getStamp());
        },"B").start();
    }
}

所有相同类型的包装类对象之间值的比较全部使用equals方法比较

Integer使用了对象缓存机制,默认范围是-128至127,推荐使用静态工厂方法valueOf获取对象实例,而不是new,因为valueOf使用缓存,而new一定会创建新的对象分配新的内存空间;

说明:对于Integer var = ?在-128至127之间的赋值,Integer对象实在IntegerCache.cache产生,会复用已有对象,这个区间的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用equals方法进行判断。

标签:JUC,版本号,编程,System,stamp,atomic,println,十九,out
From: https://www.cnblogs.com/nhgtx/p/17806046.html

相关文章

  • Shell脚本编程
    一、Shell脚本执行的几种方式1.Shell脚本中用#表示注释,相当于C语言中的//注释,但如何#位于第一行开头,并且是#!(称为Shebang)则例外,它表示该脚本使用后面指定的解释器/bin/sh解释执行,如果把这个脚本文件加上可执行权限然后执行:保存执行后:上述脚本直接以./test.sh执行,执行后会启动......
  • shell编程-循环结构
    shell循环-for语句foriin{取值范围}#for是关键字i是变量名in是关键字do#循环体的开始循环体done#循环体的结束实战1:[root@linux-serverscript]#vimfor.sh#!/usr/bin/envbash##Author:#Date:2019/**/**fo......
  • 不务正业的再次胡想——chatgpt在“智能辅助编程”外的另一个可能场景"智能论文写作辅
    在chatgpt4出来后震惊了很多人,但是很多人也觉得好像用处不大;可以说chatgpt4确实更加智能了,在语言对话上更加的智能,很多情况下已经很难分辨出这货是个机器人,但是现在这东西好像确实也没有太多的实际应用,或许更多的人用这个是当做“智能搜索引擎”来用的,而我个人却更加喜欢将chatgpt......
  • 学无止境--linux串口编程(RS485)
    备注:学习记录所用,若有高手不吝赐教,万分感谢!一、概括  linux将串口都映射成了TTY终端,所以在串口编程时,找到并使能平台的TTY,然后操作TTY终端即可。  例如对于Nuclei平台的轩辕91030M芯片设备树: uart0:serial@10013000{ compatible="sifive,uart0"; reg=<0x00x100......
  • Android并发编程高级面试题汇总(含详细解析 三)
    Android并发编程高级面试题汇总最全最细面试题讲解持续更新中......
  • (十七)C#编程基础复习——数组
    和其他编程语言一样C#也支持数组,数据是一个用来存储相同类型数据的、固定大小的、具有连续内存位置的顺序集合。数组中的每个元素都对应一个索引值,索引从0开始依次递增,我们可以通过索引来访问数据中的指定元素。假如我们要存储100名学生的分数,若使用普通变量的话可能需要定义100......
  • (十六)C#编程基础复习——可空类型
    一、可空类型在C#1.X的版本中,一个值类型的变量是不可以被赋值为null(空值)的,否则会产生异常。而在C#2.0中,新增了一个nullable类型,可以使用nullable类型定义包含null值的数据,例如,你可以在nullable<Int32>(可为空的int32类型)类型的变量中存储-2147483648到2147483647之间的任何只或......
  • chapter 13:TCP/IP 和网络编程
    学习笔记:TCP/IP和网络编程13.0摘要本章分为两个部分:TCP/IP协议与应用包括TCP/IP协议栈、IP地址、主机名、DNS、IP数据包和路由器。描述了UDP和TCP协议、端口号以及TCP/IP网络中的数据流。解释了服务器-客户端计算模型和套接字编程接口。通过使用UDP和TCP套接字的示例......
  • 熟悉编程语言
    1.最受欢迎的编程语言-TOP502.编程泛型命令式:C++、FORTRAN、BASIC面向过程:COBOL、C面向对象:python、Java、PHP、go、Objective-C、C#声明式:SQL函数式:Scala、Scheme、lisp、logo、Haskell、F#、R、ML逻辑式:prolog、C3.学习预期命令式想学习C++,面向过程学好C,面向对象......
  • (十五)C#编程基础复习——值传递、引用传递、输出传递
    通过前面的学习,我们了解了在调用带有参数的函数时,需要将参数传递给函数。在介绍这几种传递方式之前,我们先来介绍一下形式参数(形参)和实际参数(实参)这两个概念:形式参数:在定义函数阶段参数列表中定义的参数称之为形式参数,简称形参,可以将它看做变量的名称,它没有具体的值,只是用来接收......