zoukankan      html  css  js  c++  java
  • synchronized对比cas

    参考文档

    CAS底层解析:https://www.cnblogs.com/Leo_wl/p/6899716.html

    https://blog.csdn.net/tiandao321/article/details/80811103

    各种锁类型的介绍:https://www.jianshu.com/p/e7aa0a5083fb

    synchronized对比cas性能比较:https://www.jianshu.com/p/736c532869a3

    synchronized对比cas使用介绍: https://www.cnblogs.com/konck/p/9393135.html

    锁分类

    乐观锁

    读的时候不加锁,之后在写的时候才加锁。并且在写的时候,会比较当前值跟预期值是否一致,只有一致才会去执行写操作。乐观锁基本上都是由CAS来实现的。

    悲观锁

    读写的时候都加锁

    公平锁

    锁的获取遵循先进先出的原则

    不公平锁

    锁的获取遵循先进先出的原则

    JAVA中的锁分类

    偏向锁

    当只有一个线程使用某个对象的情况下,该对象可以记录使用它的线程信息,如果一直都是同一个线程使用该对象,那么整个过程就不会加锁。

    轻量级锁

    当有两个或两个以上线程访问同一个对象时,偏向锁就不行了,此时就需要使用轻量级锁。其实就是乐观锁。

    重量级锁

    如果并发访问的线程很多,并且每个线程都要锁很长时间。此时轻量级锁就会不断的自旋检查,造成CPU被占满。此时就应该使用重量级锁,重量级锁会将等待锁的线程转入阻塞状态。虽然需要用户态和内核态的切换,但是避免了死循环自旋,大大降低了cpu的使用。

    CAS compareAndSet

    它是使用硬件特性来保证原子性。在底层调用unsafe.compareAndSwapObject方法实现原子操作,当然该方法内部也是一个硬件加锁的操作。流程就是该方法会指定要修改的对象、对象的现有值和修改值。如果对象实际值跟指定现有值一致,就用修改值替换现有值。如果正在被其他线程加锁就返回修改失败。然后会有自旋检查,循环执行该原子操作,直到获取锁并执行成功。如果不限制执行次数,可能会造成死循环。

    优点

    1、不用阻塞线程,并让线程在用户态和内核态直接切换,省去切换的时间,一次阻塞和唤醒操作就需要两次切换。

    缺点

    1、如果锁一直被其他线程占用,并且自旋操作没有设置最大次数,就会造成死循环,造成cpu占用过高。

    2、只能保证某一个对象的原子性,并不能保证几个对象或一个线程同步操作。

    实现应用

     1、java.util.concurrent下的很多类,比如Atomic开头的原子操作变量,ReentrantLock,都是根据CAS实现的。如下图示

    synchronized

    实现

    在Java1.6之前,synchronized就是用悲观锁实现的。1.6之后根据不同的情况会在偏向锁、轻量级锁和重量级锁之间切换。并且是按照从轻到重的顺序切换,反之则不行。

    使用方式

    1. 修饰实例方法,为当前实例加锁,进入同步方法前要获得当前实例的锁。
    2. 修饰静态方法,为当前类对象加锁,进入同步方法前要获得当前类对象的锁。
    3. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码块前要获得给定对象的锁。

    等待唤醒机制

    synchronized的等待唤醒是通过notify/notifyAll和wait三个方法来实现的,这三个方法的执行都必须在同步代码块或同步方法中进行,否则将会报错。

    wait方法的作用是使当前执行代码的线程进行等待,notify/notifyAll相同,都是通知等待的代码继续执行,notify只通知任一个正在等待的线程,notifyAll通知所有正在等待的线程。wait方法跟sleep不一样,他会释放当前同步代码块的锁,notify在通知任一等待的线程时不会释放锁,只有在当前同步代码块执行完成之后才会释放锁。

    锁定字符串

    https://www.cnblogs.com/xrq730/p/6662232.html

    一般情况下,即使锁定字符串内容相同的不同字符串对象,是无法保证原子性操作的。但是如果调用字符串的方法intern方法,则会返回一个常量区的对象,并且在常量区,字符串值相同只有一个对象,就可以实现对同一个字符串对象进行加锁了。

  • 相关阅读:
    js你不是的那些基础问题-错误处理机制
    js你不是的那些基础问题-数据类型的转换
    js你不是的那些基础问题-布尔运算符
    js你不是的那些基础问题-函数
    js你不知的那些基础问题-对象
    js你不知的那些基础问题-数值
    小程序中ios11底部黑条兼容
    上传---FileReader
    2021年了,我才知道H5支持元素拖放!!!
    ES6常用总结(一)
  • 原文地址:https://www.cnblogs.com/suntp/p/12290883.html
Copyright © 2011-2022 走看看