JUC并发编程——CAS与原子引用(基于狂神说的学习笔记)

编程入门 行业动态 更新时间:2024-10-25 20:20:21

JUC并发编程——CAS与<a href=https://www.elefans.com/category/jswz/34/1770190.html style=原子引用(基于狂神说的学习笔记)"/>

JUC并发编程——CAS与原子引用(基于狂神说的学习笔记)

CAS

CAS与原子引用涉及到JVM以及更底层的一些知识,笔者会在JVM篇中写的更细致一点

什么是CAS

CAS 是Java设置的CPU的并发原语

Java是无法直接操作内存的

但Java可以调用C++

而C++可以操作内存

Java可以通过native类调用C++来操作内存

CAS = Compare And Set 比较并交换

CAS是:比较当前内存中的值和主内存中的值,如果这个值是期望的,那么则执行操作,如果不是就一直循环比较(自循环)

缺点:

1、自循环会耗时

2、一次性职能保证一个共享变量的原子性

3、会存在ABA问题

/*** Atomically sets the value to newValue* if the current value code == expectedValue,* with memory effects as specified by VarHandle#compareAndSet.** @param expectedValue the expected value* @param newValue the new value* @return true if successful. False return indicates that* the actual value was not equal to the expected value.*/
public final boolean compareAndSet(int expectedValue, int newValue) {return UpareAndSetInt(this, VALUE, expectedValue, newValue);
}
package CAS;import java.util.concurrent.atomic.AtomicInteger;public class casDemo {// CAS 是CPU的并发原语// compareAndSet:比较并交换public static void main(String[] args) {AtomicInteger atomicInteger = new AtomicInteger(2020);// public final boolean compareAndSet(int expectedValue, int newValue)// expectedValue:期望值    newValue:更新值// 比较,如果期望值达到了,则变为更新值,否则就不跟新atomicIntegerpareAndSet(2020,2023);System.out.println(atomicInteger.get());System.out.println(atomicIntegerpareAndSet(2020, 2023));}
}

原子引用

带版本号的原子操作 解决ABA问题! 与乐观锁很相似!

package CAS;import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;public class casDemo02 {
// AtomicStampedReference 注意,如果泛型时一个包装类,注意对象的引用问题public static void main(String[] args) {AtomicStampedReference<Integer> atomicInteger = new AtomicStampedReference<>(1,1);new Thread(()->{// 获得目前的版本号(时间戳)int stamp = atomicInteger.getStamp();System.out.println("A1=>"+stamp);try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(atomicIntegerpareAndSet(1, 2, atomicInteger.getStamp(), atomicInteger.getStamp() + 1));System.out.println("A2=>"+atomicInteger.getStamp());System.out.println(atomicIntegerpareAndSet(2, 1, atomicInteger.getStamp(), atomicInteger.getStamp() + 1));System.out.println("A3=>"+atomicInteger.getStamp());},"A").start();new Thread(()->{// 获得目前的版本号(时间戳)int stamp = atomicInteger.getStamp();System.out.println("B1=>"+stamp);try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(atomicIntegerpareAndSet(1, 6, stamp, stamp + 1));System.out.println("B1=>"+atomicInteger.getStamp());},"B").start();}
}

注意:

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

在示例中,我们一开始使用的expectedRefrence 和 newReference 都是大于127的且使用new获取对象,因此,内存中创造了新的对象分配新的空间,所以使用cas时一直为false

更多推荐

JUC并发编程——CAS与原子引用(基于狂神说的学习笔记)

本文发布于:2023-12-07 10:14:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1670953.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:原子   学习笔记   JUC   CAS   狂神说

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!