zoukankan      html  css  js  c++  java
  • 6.23Java多线程CAS原子操作

    6.23Java多线程CAS原子操作

    锁的分类

    • 悲观锁:

      • synchronized是独占锁(悲观锁)

      • 其特点是

        • 会导致其他所有需要锁的线程挂起,等待持有锁的线程释放资源

    • 乐观锁(Compare and Swap:比较与交换)

      • 每次操作不加锁,假设没有冲去取完成某项操作

        • 如果因为冲突导致失败则会重试到成功为止

      • 乐观锁的实现--->这个思想就是CAS思想

        • 方法:

          • 三个值:

            • 当前内存值V

            • 旧的预期值A

            • 将更新的值B

          • 先获取到内存中当前的内存之V

          • 将V与A比较

          • 如果V和A相等,将B赋值给V并且返回true

          • 否则什么都不做返回false

            • if(V == A){
                 V = B;
                 return true;
              }else {
                 return false;
              }
          • 特点:

            • CAS是一组原子操作,不会被外部打断

            • 属于硬件级别的操作(利用CPU的CAS指令,借助JNI来完成的非阻塞算法),效率比加锁操作高

          • ABA问题:

            • 如果变量V初次读取的时候是A,准备赋值的时候检查也是A能否说明它没有被其他线程修改过?

            • 如果这段期间曾经被改成B然后又改回A那么CAS操作会误认为它从来没有被修改过

            • 通过日志查看操作来确定没有被动过--->C或C++实现原理

    • 按照可沿用属性分类:

      • 可重入锁

        • 公平锁

        • 不公平锁

        (根据是否按照队列顺序进行操作来划分)

      • 不可重入锁

    • 自旋锁

    操作核心

    两大核心值:

    version--->1--->被更新以后的版本变为2

    number-->10--->9更新的时候比较版本是否相同,版本相同更新,版本不同不更新。

    比较并交换数据

    CAS原子性操作--->利用Java当中自带的类实现
    package thread.rearrangement;

    import java.util.concurrent.atomic.AtomicInteger;

    /**
    * CAS比较并交换
    * @since JDk 1.8
    * @date 2021/6/23
    * @author Lucifer
    */
    public class CAS {

       /*先加入资源类对象*/
       //库存对象
       private static AtomicInteger stock = new AtomicInteger(5);
       /*
       Atomic原子性操作里面都会用到原子性的思想
       里面用的不是synchronized同步锁
       而是用CAS的思想,效率高,是硬件级别的操作
        */

       public static void main(String[] args) {

           /*利用lambda表达式开辟五个线程*/
           for (int i=0; i<5; i++){
               new Thread(() -> {

                   /*模拟延时*/
                   try {
                       Thread.sleep(1000);
                  }catch (InterruptedException e){
                       System.out.println(e.getMessage());
                       e.printStackTrace();
                  }

                   /*抢购库存的数据,就是减少数据*/
                   Integer left = stock.decrementAndGet();
                   /*
                   这个方法的源码当中就存在CAS的思想
                   */

                   /*判断*/
                   if (left<1){
                       System.out.println("抢完了...");
                       return;
                  }

                   /*打印出获取到资源的线程*/
                   System.out.println(Thread.currentThread().getName() + "抢了一件商品");
                   System.out.println("还剩" + left);

              }).start();
          }
      }

    }

     

    It's a lonely road!!!
  • 相关阅读:
    webstorm2018.1 汉化
    微信小程序转发微信小程序转发
    微信小程序下拉刷新和上拉加载的实现
    微信小程序基本目录结构学习
    JavaScript中闭包的写法和作用详解
    前端面试 问题汇总
    js 循环
    vue.js的手脚架vue-cli项目搭建的步骤
    js 条件判断
    数组
  • 原文地址:https://www.cnblogs.com/JunkingBoy/p/14923093.html
Copyright © 2011-2022 走看看