zoukankan      html  css  js  c++  java
  • 四、常见的锁

    一、悲观锁

    概念:在获取数据时会先加锁,确保数据不会被别的线程修改。

    场景:适合写操作多的场景,先加锁可以保证写操作时数据正确。

    实现:synchronized关键字和Lock的实现类都是悲观锁。

    二、乐观锁

    概念:获取数据时认为不会有别的线程修改数据,所以不会上锁,但是在更新时会判断有没有别的线程更新了这个数据。

    场景:适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升。

    实现:使用无锁编程来实现,常见的有CAS算法和版本号机制。(Java原子类中的递增操作就通过CAS自旋实现)

    三、公平锁和非公平锁

    概念:公平锁遵循FIFO(先进先出)原则的,先到的线程会优先获取资源,后到的会进行排队等待。非公平锁不遵循FIFO。

    区别

    1、公平锁可以保证“雨露均沾”。

    2、非公平锁有着更高的性能。

    源码上看,公平锁的比非公平锁的多一步判断。

    恢复挂起的线程到真正锁的获取有一定时间差,从开发人员来看这个时间微乎其微,但从CPU角度来看,这个时间差可以被非公平锁抢占,可以尽量减少CPU空闲时间。

    非公平锁减少线程的开销,当1个线程请求锁获取同步状态,然后释放同步状态,因为不需要考虑是否还有前驱节点,所以刚释放锁的线程在此刻更容易再次获取同步状态。

    四、可重入锁

    概念:同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提,锁的对象是同一个对象)。不会因为之前已经获取过还没释放锁而阻塞。

    实现:ReentrantLock、synchronized

    五、死锁

    概念:两个或两个以上的线程再执行过程中,因争夺资源而造成的一种互相等待的现象。

    排查死锁:jps、jstack、jconsole

    六、自旋锁(CAS)

    概念:是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,当线程发现锁被占用时,会不断循环判断锁的状态,直到获取。这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU。

    七、偏向锁

    概念

    1、在没有其他线程竞争的时候,一直偏向偏心当前线程,当前线程可以一直执行。

    2、当一段同步代码一直被同一个线程多次访问,由于只有一个线程那么该线程在后续访问时便会自动获得锁。它的出现是为了解决只有在一个线程执行同步时提高性能

    技术实现:一个synchronized方法被一个线程抢到了锁时,那这个方法所在的对象就会在其所在的Mark Word中将偏向锁修改状态位,同时还占用前54位来存储线程指针作为标识。若该线程再次访问同一个synchronized方法时,该线程只需去对象头的Mark Word 中去判断一下是否有偏向锁指向本身的ID,无需再进入Monitor去竞争对象了。

    八、轻量锁

    概念:有线程来参与锁的竞争,但是获取锁的冲突时间极短。其本质就是自旋锁。

  • 相关阅读:
    P1311 选择客栈 模拟 ( + st表)
    P2656 采蘑菇 tarjan + spfa
    送别
    10.16互测题 贪心+数论
    poj 2823 Sliding Window 单调队列
    P1036 选数 dfs
    P3370 【模板】字符串哈希
    A Tear or A Smile?
    KMP 算法
    jQuery 中 attr 和 prop 的区别
  • 原文地址:https://www.cnblogs.com/shiblog/p/15716230.html
Copyright © 2011-2022 走看看