码迷,mamicode.com
首页 > 编程语言 > 详细

Java的锁

时间:2020-01-30 22:46:51      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:lock   失败   java   无锁   rev   就是   sync   线程阻塞   超过   

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

 

技术图片

 

乐观锁和悲观锁

简单解释就是,悲观锁认为在一个线程使用数据的时候,一定会有别的线程来修改数据,所以在使用数据时候就加上一个锁,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无论读操作还是写操作,添加的锁都是都是独享锁。

 

 

Java的锁

标签:lock   失败   java   无锁   rev   就是   sync   线程阻塞   超过   

原文地址:https://www.cnblogs.com/CherryTab/p/12244074.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!