• 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方法,则会返回一个常量区的对象,并且在常量区,字符串值相同只有一个对象,就可以实现对同一个字符串对象进行加锁了。

  • 相关阅读:
    ionic + cordova+angularJs 搭建的H5 App完整版总结
    在DevExpress程序中使用GridView直接录入数据的时候,增加列表选择的功能
    【Web动画】SVG 线条动画入门
    闲来无聊,研究一下Web服务器 的源程序
    PHP实现RTX发送消息提醒
    关于AngularJS(1)
    项目总结12:bootstrap-select下拉框模糊搜索
    JAVA读取XML文件并解析获取元素、属性值、子元素信息
    项目总结11:Centos部署JDK+Tomcat+MySQL文档(阿里云-网易云-华为云)
    项目总结10:通过反射解决springboot环境下从redis取缓存进行转换时出现ClassCastException异常问题
  • 原文地址:https://www.cnblogs.com/suntp/p/12290883.html
Copyright © 2020-2023  润新知