• Java的锁


    本人曾接手过一些很奇怪的代码,基本到处都是是volatile和硬加锁,说是为了安全,就不怕死锁和性能太差吗?其实我压根不想改这种东西了,既然能过code review那么说明什么问题了?我不会让自己成为这类人。

    参考自

    https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651749434&idx=3&sn=5ffa63ad47fe166f2f1a9f604ed10091&chksm=bd12a5778a652c61509d9e718ab086ff27ad8768586ea9b38c3dcf9e017a8e49bcae3df9bcc8&scene=38#wechat_redirect

    乐观锁和悲观锁

    简单解释就是,悲观锁认为在一个线程使用数据的时候,一定会有别的线程来修改数据,所以在使用数据时候就加上一个锁,synchronizied和lock就是如此。

    乐观锁是一种使用不直接加锁,当修改时再判断数据是否被其他线程修改之类的无锁编程。CAS,你不需要手动设置锁。

    CAS很简单,只讲缺点

    ABA问题

    循环开销大

    只能保证一个原子量

    自选锁和适应性自旋锁

    因为自旋锁缺点比较明显,就是cpu一直再切换,因此有了适应性自旋锁

     自选等待实际上只是减少cpu的切换性能浪费,将线程挂起也是占用着cpu的资源,因此现在为了避免过度等待也有不同的等待策略。

    无锁,偏向锁,轻量级锁,重量级锁

    上面我们介绍的CAS原理及应用即是无锁的实现。无锁无法全面代替有锁,但无锁在某些场合下的性能是非常高的。

    偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。

    在大多数情况下,锁总是由同一线程多次获得,不存在多线程竞争,所以出现了偏向锁。其目标就是在只有一个线程执行同步代码块时能够提高性能。

    是指当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。

    若当前只有一个等待线程,则该线程通过自旋进行等待。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁。

    公平锁和非公平锁

    可重入锁和不可重入锁

    当线程尝试获取锁时,可重入锁先尝试获取并更新status值,如果status == 0表示没有其他线程在执行同步代码,则把status置为1,当前线程开始执行。如果status != 0,则判断当前线程是否是获取到这个锁的线程,如果是的话执行status+1,且当前线程可以再次获取锁。而非可重入锁是直接去获取并尝试更新当前status的值,如果status != 0的话会导致其获取锁失败,当前线程阻塞。

     独享锁和共享锁

     ReentrantLock虽然有公平锁和非公平锁两种,但是它们添加的都是独享锁。根据源码所示,当某一个线程调用lock方法获取锁时,如果同步资源没有被其他线程锁住,那么当前线程在使用CAS更新state成功后就会成功抢占该资源。而如果公共资源被占用且不是被当前线程占用,那么就会加锁失败。所以可以确定ReentrantLock无论读操作还是写操作,添加的锁都是都是独享锁。

     

     
    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    SQLite的总结与在C#的使用
    Linq中比较字符串类型的日期
    C#中委托,匿名函数,lamda表达式复习
    MYSQL中SUM (IF())
    C#在属性中用Lambda语法
    Mysql绿色版安装和遇到的问题
    FormsAuthentication权限管理
    存储过程中高性能安全式SQL拼接
    JavaScript实现搜索联想功能
    JavaScript组成
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12244074.html
Copyright © 2020-2023  润新知