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

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

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

所以使用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. getAddress和getHostAddress的区别

    getAddress方法和getHostAddress类似,它们的唯一区别是getHostAddress方法返回的是字符串形式的IP地址,而getAddress方法返回的是byte数组形式的IP地址.

  2. mindxdl--common--log_record.go

    // Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common define co ...

  3. go cookie session

    https://astaxie.gitbooks.io/build-web-application-with-golang/content/zh/06.1.html

  4. Huawei OJ 题解 - 1. A + B Problem - Go 参考解答

    # Huawei OJ 题解 - 1. A + B Problem - Go 参考解答## 简介- 详情:http://oj.rnd.huawei.com/problems/1/details- 难度 ...

  5. centos8换可用公网yum源

    这个咋说呢,总之就是非常简单 百度上找一个公网源替换进去就好 但是就是麻烦,在此做个笔记,也当给大家一个现成的范例 以下为https://vault.centos.org官网源的一个简单的替换脚本,一 ...

  6. 【Java并发001】使用级别:线程相关知识

    一.前言 本文介绍Java线程相关知识(不包括线程同步+线程通信,这个内容在笔者的另一篇博客中介绍过了),包括:线程生命周期.线程优先级.线程礼让.后台线程.联合线程. 二.线程生命周期 2.1 引子 ...

  7. i春秋登录

    打开是个普普通通的表单提交网页 查看源码,没什么东西 抓包试试再 没找到什么有用的信息 尝试注入 用户名admin' or '1'='1 密码随便输 弹出密码错误 再试试admin' or '1'=' ...

  8. Kafka教程(一)基础入门:基本概念、安装部署、运维监控、命令行使用

    Kafka教程(一)基础入门   1.基本概念   背景   领英->Apache   分布式.消息发布订阅系统   角色   存储系统   消息系统   流处理平台-Kafka Streami ...

  9. 【Shell案例】【tail/head/sed、echo $res ·· cat和管道】2、打印文件的最后5行

    描述经常查看日志的时候,会从文件的末尾往前查看,于是请你写一个 bash脚本以输出一个文本文件 nowcoder.txt中的最后5行示例:假设 nowcoder.txt 内容如下: #include& ...

  10. 过压保护芯片,高输入电压(OVP)

    PW2606是一种前端过电压和过电流保护装置.它实现了广泛的输入电压范围从2.5V到40V.过电压阈值可在外部编程或设置为内部默认设置.集成功率路径nFET开关的超低电阻确保了更好的性能电池充电系统应 ...