前面的偏向锁,轻量级锁,重量级锁都是悲观锁,

都会认为必须要对操作对象进行互斥访问,不然就会产生异常, 所以线程只供一个线程使用,阻塞其他线程,是悲观的

在某些情况下,同步的耗时远大于线程切换的时间,互斥就有点多余了

所以使用CAS compare ans swap

一个资源 对应一个 tig 为1表示被占用,0表示未被占用

两个线程(称为AB) 均想获取该资源,即都希望当前tig为0 并由自己将其置为1

用代码表示: 逻辑就是这样的

int cas(long* address,long oldValue,long newValue)
{
if(*address!=oldValue){
return 0;
}
*address = newValue;
return 1; }

如果csa失败 则等待。

如果只看代码 同样也是无法实现互斥的,代在底层,我们的CAS 是原子性 的。比较和交换两个操作是一体的。

还有就是底层的循环等待一般也不是死循环,是有限制的

Java中的使用示例:

不使用CAS:

public class Main {

    public static void main(String[] args) {

        int i;
for (i = 0; i < 4; i++) {
new casTest().start();
}
}
} class casTest extends Thread{
public static int a = 0; @Override
public void run() {
while(a<1000){
System.out.println(getName() + " "+a++);
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

输出:

Thread-0   993
Thread-2 994
Thread-1 995
Thread-3 996
Thread-0 997
Thread-1 998----
Thread-2 998----
Thread-0 999
Thread-3 999

只截了最后几行

可以看到 标记处 两个线程输出了同样的数

代码线程不安全

下面我们尝试使用互斥锁

public class Main {

    public static void main(String[] args) {

        int i;
for (i = 0; i < 4; i++) {
new casTest().start();
} }
} class casTest extends Thread{
public static int a = 0; @Override
public void run() {
while(a<1000){
System.out.println(getName() + " "+a++);
synchronized (Math.class){
a++;
} } }
}

输出:

Thread-2   982
Thread-2 984
Thread-2 986
Thread-2 988
Thread-2 990
Thread-2 992
Thread-2 994
Thread-2 996
Thread-2 998
Thread-1 502
Thread-0 586

无重复

下面我们用 CAS:

import java.util.concurrent.atomic.AtomicInteger;

public class Main {

    public static void main(String[] args) {

        int i;
for (i = 0; i < 4; i++) {
new casTest().start();
} }
} class casTest extends Thread{
// public static int a = 0;
public static AtomicInteger integer = new AtomicInteger(0); @Override
public void run() {
while(integer.get()<1000){
System.out.println(getName() + " "+integer.incrementAndGet()); } }
}

输出:

Thread-1   993
Thread-1 994
Thread-1 995
Thread-1 996
Thread-1 997
Thread-0 960
Thread-0 999
Thread-0 1000
Thread-2 943
Thread-1 998

顺序不同是因为输出的缘故

但不会出现重复,即实现了互斥

下面点进去看看源码:

确实用的是CAS

再往下一点:

这里是native方法

不同系统的代码可能不同,都是基于本地硬件进行CAS操作 c++实现

找到了一个源码的截图:

框框处调用了汇编命令

CAS 悲观锁 乐观锁的更多相关文章

  1. 最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

    在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 01.乐观锁 vs 悲观 ...

  2. Java并发 行级锁/字段锁/表级锁 乐观锁/悲观锁 共享锁/排他锁 死锁

    原文地址:https://my.oschina.net/oosc/blog/1620279 前言 锁是防止在两个事务操作同一个数据源(表或行)时交互破坏数据的一种机制. 数据库采用封锁技术保证并发操作 ...

  3. Java最全锁剖析:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

    乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会 ...

  4. Hibernate悲观锁/乐观锁

    如果需要保证数据访问的排它性,则需对目标数据加"锁",使其无法被其它程序修改 一,悲观锁 对数据被外界(包括本系统当前的其它事务和来自外部系统的事务处理)修改持保守态度,通过数据库 ...

  5. SQL Server 锁机制 悲观锁 乐观锁 实测解析

    先引入一些概念,直接Copy其他Blogs中的,我就不单独写了. 一.为什么会有锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 1.丢失更新 A,B两个用户读同一数据并进行修改,其中 ...

  6. Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁

    Optimistic concurrency control https://en.wikipedia.org/wiki/Optimistic_concurrency_control Optimist ...

  7. Mysql悲观锁乐观锁区别与使用场景

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  8. 【MySQL】悲观锁&乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...

  9. innodb 悲观锁,乐观锁

    转 http://www.cnblogs.com/chenwenbiao/archive/2012/06/06/2537508.html CREATE TABLE `products` ( `id` ...

  10. 谈谈mysql的悲观和乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.之前有写过一篇文章关于并发的处理思路和解决方案,这里我单独将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍一 ...

随机推荐

  1. 👍SpringSecurity单体项目最佳实践

    SpringSecurity单体项目最佳实践 到这里,我们的SpringSecurity就已经完结啦,文章中可能有些地方不能做到全面覆盖,视频教程地址 初始项目地址 完成项目地址 1.搭建环境 建议下 ...

  2. vue3中的defineProps,watch,computed

    在vue3的setup语法糖中,defineProps不需要引入了 <script setup> import { computed } from '@vue/reactivity'; i ...

  3. Go语言核心36讲31

    我们在前两篇文章中讨论了互斥锁.读写锁以及基于它们的条件变量,先来总结一下. 互斥锁是一个很有用的同步工具,它可以保证每一时刻进入临界区的goroutine只有一个.读写锁对共享资源的写操作和读操作则 ...

  4. VS使用web deploy发布到远程服务器

    如果是先安装 web deploy后安装iis的功能,需要在iis功能安装好后,修复下web deploy(直接运行web deploy的安装程序有修复)(本人也死在这里) 1.iis开启管理服务,和 ...

  5. 5 STL-string

    ​ 重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦!  生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦! 写在前面,本篇章主要介绍S ...

  6. 2 c++编程-核心

    ​ 重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦! 本章是继上篇 c++编程-基础 之后的 c++ 编程-核心. 生命就像一朵花,要拼尽 ...

  7. python3获取列表逆序的五种方式

    前言 我们将这几种方式分为两类,一种是对列表本身进行操作,改变对应内存中的值,另一种是带有返回值的,相当于拷贝了一份 对列表内存中进行操作 sort() 函数 a = [1,2,3,4] a.sort ...

  8. Django基础笔记2(分页)

    Django Django自带的分页功能 from django.core.paginator import Paginator # 用于分页 curPage = request.GET.get('p ...

  9. Spring Boot回顾

    一.概述 1.Spring的优缺点 优点 无需开发ELB,通过IOC和AOP,就可以使用POJO(简单的Java对象)实现ELB的功能 缺点: 依赖管理导入Maven耗时耗力 注解繁琐 2.Sprin ...

  10. ArcObjects SDK开发 014 MapSurround和普通Element

    1.如何获取MapSurround 和获取MapFrame类似,如果你已经获取指北针.比例尺等对象,可以通过IGraphicsContainer的FindFrame函数获取.如果没有,则通过IGrap ...