首页 > 其他分享 >CAS 悲观锁 乐观锁

CAS 悲观锁 乐观锁

时间:2023-02-12 10:45:15浏览次数:36  
标签:Thread CAS 乐观 int 线程 悲观 static public

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

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

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

所以使用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++实现

找到了一个源码的截图:

框框处调用了汇编命令

标签:Thread,CAS,乐观,int,线程,悲观,static,public
From: https://www.cnblogs.com/cndccm/p/17113385.html

相关文章

  • 悲观锁和乐观锁
    悲观锁:认为线程问题一定会发生,在操作数据之前就获取锁,确保线程串行执行。列如Synchronized、lock乐观锁:认为线程问题不一定发生,因此不加锁,只是在更新数据时去判断有没有其......
  • Kubernetes(k8s)控制器(四):ReplicaSet
    目录一.系统环境二.前言三.ReplicaSet概览四.ReplicaSet工作原理五.ReplicaSet使用场景六.创建ReplicaSet七.扩展replicaset副本数一.系统环境服务器版本docker软件......
  • [蓝桥杯 2019 省 A] 组合数问题-Lucas定理、数位dp
    洛谷的题目链接:https://www.luogu.com.cn/problem/P8688Lucas定理,把\(k|binom{i}{j}\)转换成在k进制下存在某个数位i比j小,再转换成反面计算每一位i都比j大,然后就是经典......
  • switch case多选择结构/查看反编译类文件
    switchcase多选择结构switch中变量类型可以是byte,short,int或char,从javaSE7开始,switch支持字符串类型。publicclassdemo09{publicstaticvoidmain(String[]......
  • SpringBoot工程入门case
    SpringBoot的设计目的是用来简化Spring应用的初始搭建以及开发过程。SpringBoot入门案例:1、创建一个新module  2、除pom和src文件剩余都删除。  3、在src.com......
  • ICMPv6 Multicast Listener Report Message v2
    No.TimeSourceDestinationProtocolInfo70.164795fe80::f8ae:aae:ee9a:bdc0ff02::16ICMPv6MulticastListenerReportMessagev2Frame......
  • C语言填空:周几判断 switch case应用
    /*假设今天是星期日,编写一个程序,求123456天后是星期几*/#include<stdio.h>intmain(){intn,iday;printf("请输入天数:");scanf("%d",【1】);【2】;switch(【3】)......
  • C语言填空:switch case练习
    /*下列程序的功能为:实现加、减、乘、除四则运算。*///【1】【2】【3】【4】【5】【6】【7】【8】【9】【10】#include<stdio.h>voidmain(){inta,b,d;......
  • Codeforces Round #514 (Div. 2).A. Cashier 做了个优化 还行
    A.Cashiertimelimitpertest2secondsmemorylimitpertest256megabytesinputstandardinputoutputstandardoutputVasyahasrecentlygotajobasacashieratal......
  • .NET Cas 认证(基于Cookie)
    项目需求:开发系统A对接客户公司的cas认证系统B,实现单点登录业务场景描述:打开A系统地址,判断Cookie是否登录状态,如果未登录,跳转B登录界面;如果已登录,直接获取到cookie......