CAS

CAS

缺点:循环会耗时;一次性只能保持一个共享变量的原子性;ABA问题

package juc.cas;

import java.util.concurrent.atomic.AtomicInteger;

public class CASDemo {

    // CAS  compareAndSet比较并交换 是CPU的并发原语
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
// 如果是期望的值就更新,否则一直循环
System.out.println(atomicInteger.compareAndSet(2020, 2021));// true
System.out.println(atomicInteger.get());
atomicInteger.getAndIncrement();// 2021 System.out.println(atomicInteger.compareAndSet(2020, 2021));// false
System.out.println(atomicInteger.get());// 2022 }
}
  • ABA问题
package juc.cas;

import java.util.concurrent.atomic.AtomicInteger;

public class CASDemo {

    public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
// A对资源操作过了,又改回去了
System.out.println(atomicInteger.compareAndSet(2020, 2021));// true
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(2021, 2020));// true
System.out.println(atomicInteger.get()); // B不知情
System.out.println(atomicInteger.compareAndSet(2020, 2022));// true
System.out.println(atomicInteger.get()); }
}
  • 原子引用解决ABA问题
package juc.cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference; public class CASDemo { public static void main(String[] args) {
// !如果泛型是一个包装类,注意对象的引用问题
// 带版本号的原子操作
AtomicStampedReference<Integer> atomicInteger = new AtomicStampedReference<>(1, 1); new Thread(()->{
// 获得版本号
System.out.println("A1->" + atomicInteger.getStamp()); try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(atomicInteger.compareAndSet(1, 2,
atomicInteger.getStamp(), atomicInteger.getStamp() + 1));
System.out.println("A2->" + atomicInteger.getStamp()); System.out.println(atomicInteger.compareAndSet(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->" + atomicInteger.getStamp()); try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(atomicInteger.compareAndSet(1, 6, stamp, stamp + 1));
System.out.println("B2->" + atomicInteger.getStamp()); },"B").start();
}
}
  • 注意!:Integer有对象缓存机制

Unsafe类

@IntrinsicCandidate
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
v = getIntVolatile(o, offset);
} while (!weakCompareAndSetInt(o, offset, v, v + delta));// 获取内存地址中的值,自旋锁
return v;
}
public final int getAndIncrement() {
return U.getAndAddInt(this, VALUE, 1);
}

各种锁的理解

  • 公平锁:不能插队,必须先来后到
  • 非公平锁:可以插队,默认都是非公平
public ReentrantLock() {
sync = new NonfairSync();
} public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
  • 可重入锁:拿到外面的锁,就可以拿到里面的锁,自动获得
package juc.lock;

public class Demo1 {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(()->{
phone.sms();
}, "A").start(); new Thread(()->{
phone.sms();
}, "B").start(); /**
* Asms
* Acall
* Bsms
* Bcall
*/
}
} class Phone{
public synchronized void sms(){
System.out.println(Thread.currentThread().getName() + "sms");
call();
} public synchronized void call(){
System.out.println(Thread.currentThread().getName() + "call");
}
}
package juc.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Demo2 {
public static void main(String[] args) {
Phone2 phone = new Phone2();
new Thread(()->{
phone.sms();
}, "A").start(); new Thread(()->{
phone.sms();
}, "B").start(); /**
* Asms
* Acall
* Bsms
* Bcall
*/
}
} class Phone2{
Lock lock = new ReentrantLock(); public void sms(){ lock.lock();// 和call的锁不同,是两把锁
try {
System.out.println(Thread.currentThread().getName() + "sms");
call();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void call(){ lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "call");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
  • 自旋锁
package juc.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; public class MySpinlock {
AtomicReference<Thread> atomicReference = new AtomicReference<>();
// 加锁
public void myLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + " -> mylock"); // 自旋锁
while (!atomicReference.compareAndSet(null, thread)){ }
} // 解锁
public void myUnLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + " -> myUnlock");
atomicReference.compareAndSet(thread, null);
} public static void main(String[] args) throws InterruptedException {
MySpinlock mySpinlock = new MySpinlock();
new Thread(()->{
mySpinlock.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
e.printStackTrace();
} finally {
mySpinlock.myUnLock();
}
}, "A").start(); TimeUnit.SECONDS.sleep(1); new Thread(()->{
mySpinlock.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
e.printStackTrace();
} finally {
mySpinlock.myUnLock();
}
}, "B").start(); /**
* A -> mylock
* B -> mylock
* A -> myUnlock
* B -> myUnlock
*/
}
}
  • 死锁

    • 使用“jps -l”定位进程号
    • 使用“jstack 进程号”寻找死锁问题

java CAS及各种锁的更多相关文章

  1. Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS

    首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁.传统的关系型数据库里边就用到了很 ...

  2. JAVA CAS原理深度分析 volatile,偏向锁,轻量级锁

    JAVA CAS原理深度分析 http://blog.csdn.net/hsuxu/article/details/9467651 偏向锁,轻量级锁 https://blog.csdn.net/zqz ...

  3. Java 中的各种锁和 CAS + 面试题

    Java 中的各种锁和 CAS + 面试题 如果说快速理解多线程有什么捷径的话,那本文介绍的各种锁无疑是其中之一,它不但为我们开发多线程程序提供理论支持,还是面试中经常被问到的核心面试题之一.因此下面 ...

  4. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  5. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

  6. Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例

    概要 前面对"独占锁"和"共享锁"有了个大致的了解:本章,我们对CountDownLatch进行学习.和ReadWriteLock.ReadLock一样,Cou ...

  7. Java多线程系列--“JUC锁”05之 非公平锁

    概要 前面两章分析了"公平锁的获取和释放机制",这一章开始对“非公平锁”的获取锁/释放锁的过程进行分析.内容包括:参考代码获取非公平锁(基于JDK1.7.0_40)释放非公平锁(基 ...

  8. Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock

    概要 Java的JUC(java.util.concurrent)包中的锁包括"独占锁"和"共享锁".在“Java多线程系列--“JUC锁”02之 互斥锁Ree ...

  9. Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

    概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...

  10. Java CAS 和ABA问题

    独占锁:是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁. 乐观锁:每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功 ...

随机推荐

  1. 【转载】 梯度的直观理解_谈谈优化算法之一(动量法、Nesterov法、自然梯度法)

    原文地址: https://blog.csdn.net/weixin_34613462/article/details/112333623 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA ...

  2. 分布式深度学习计算框架依赖环境——NCCL的安装

    分布式深度学习计算框架(MindSpore, PyTorch)依赖环境--NCCL, NCCL提供多显卡之间直接进行数据交互的功能(可以跨主机进行). 注意: 本文环境为  Ubuntu18.04 以 ...

  3. 【转载】 一块GPU顶数千个CPU内核,英伟达的这个强化学习利器技术细节终于公开了

    原文地址: https://mp.weixin.qq.com/s/FmFqmIqmknkpBQbNb2ioDA ============================================ ...

  4. Mybatis-Plus系统化学习之注解的使用

    1.背景 注解的使用 大多数请求下我们默认为有如下对应关系 1.数据库中的表名 ---> java中的实体类名 (下划线与驼峰转换) 2.数据中的id为主键 3.数据库中的字段名---> ...

  5. tomcat发布两个项目报错webAppKey重复设置

    两个项目的web.xml中都有一个日志监听器配置 <listener> <listener-class> org.springframework.web.util.Log4jC ...

  6. Xinference实战指南:全面解析LLM大模型部署流程,携手Dify打造高效AI应用实践案例,加速AI项目落地进程

    Xinference实战指南:全面解析LLM大模型部署流程,携手Dify打造高效AI应用实践案例,加速AI项目落地进程 Xorbits Inference (Xinference) 是一个开源平台,用 ...

  7. 如何使用Typora写出自己的第一个博客

    markdown的使用说明 一.标题 语法:# 这是一级标题 ##这是二级标题...... 代码: # 这是一级标题 ## 这是二级标题 快捷键: Ctrl+数字:数字1-6可以快速将选中的文本调成对 ...

  8. MacPorts 使用

    安装 安装苹果命令行开发工具: xcode-select --install 下载并打开 MacPorts 安装包. 使用 MacPorts 中的软件包称为 port. sudo port selfu ...

  9. 如何阅读 diff 命令的输出

    diff 命令有三种模式:上下文模式(context),合并模式(unified)和普通模式(normal).其中最常用的是合并模式. 合并模式 diff -u f1 f2 --- f1 2024-0 ...

  10. 【ETL工具】DataX + DataXWeb 初使用过程记录

    版本:DataX v202309  DataXWeb 2.1.3预发布版 DataX: Github:https://github.com/alibaba/DataX 功能介绍文档:https://g ...