java并发中的锁:

什么是线程安全:程序在多线程环境下,对于共享的,可修改的数据的正确性。如果数据不是共享的,或者不是可修改的,也就不存在线程安全问题。

保证线程安全的两个方法:(1)封装::通过封装,我们可以将对象内部状态隐藏、保护起来。

                                           (2)不可变:java目前还没有真正意义的不可变

线程安全需要保证的基本特性:(1)原子性:相关的一系列操作要么全都执行成功,要么全都执行失败,---一般通过同步机制实现。

                                                   (2)可见性:共享数据被某一个线程修改完以后,其他线程立即可见。---volatile实现

                                                   (3)一致性:保证程序内部串行语义,避免指令重排。

 

1.关键字:

(1)synchronized 关键字:可以作用于 变量  方法  类 级别 可以保证 原子性  ,可见性。底层是使用monitorenter/monitorexit块实现-----monitor块java6之前完全依赖于操作系统层面的  互斥锁 。现代的jdk中,jvm提供了三种Monitor实现:偏斜锁  重量级锁   轻量级锁。JVM 对于synchronized的优化就在于 锁的升级和降级

锁的升级和降级:当jvm检测到线程之间不同的竞争状态时,会自动切换到合适的锁级别

*当没有竞争出现时,默认会使用偏斜锁,该依据假设是:大多数的对象在他的生命周期中,最多会被一个线程锁定。可以降低无竞争状态下的开销。

*锁的升降级时机:当有另外的一个线程试图锁定,已经被偏斜锁,锁定的对象时----jvm首先会撤销偏斜锁,然后升级为轻量级锁机制来试图获取锁,如果不成功,在升级为重量级锁机制来试图获取锁。

(2)volatile关键字:只能作用于 变量  层面,可以保证变量的  可见性 ,可以避免指令的重排序

*工作原理:当某个线程用到被volatile关键字修饰的变量时,会告诉该线程,当前工作内存的数据不能保证是准确的,必须从主存中重新获取。

2.可重入锁:当一个线程已经获取到锁了,当他再次试图获取锁的时候,便会自动获取成功。(原因:以线程为单位)

基本单位:以持有锁的线程为单位

ReentrantLock锁:implement Lock 接口  可以在构造方法中设置  公平锁 (true) 非公平锁 (false)  默认为false.

公平锁的机制:倾向于将锁赋予等待时间最久的线程,但synchronized关键字是基于非公平的,通常情况下不会采用公平锁,因为他会增加系统的开销。同时,java默认的调度算法很少会产生“饥饿”线程。

*synchronized关键字和ReentrantLock用法的比较:操作ReentrantLock可以像操作普通对象一样,可以利用其内部提供的方法进行精细的同步操作,一般与java.util.concurrent.Condition一同使用,Condition的运行机制可以理解为将wait(),notatify(),notatifyAll(),转化为可操作的对象。使用时,必须在finally{}中进行资源的释放。

Lock锁的用例:

带超时的获取锁尝试。可以判断是否有线程,或者某个特定线程,在排队等待获取锁。可以响应中断请求
 

 

3.自旋锁:竞争锁的失败的线程,并不会真实的在操作系统层面挂起等待,而是JVM会让线程做几个空循环(基于预测在不久的将来就能获得),在经过若干次循环后,如果可以获得锁,那么进入临 界区,如果还不能获得锁,才会真实的将线程在操作系统层面进行挂起。 

适用场景:自旋锁可以减少线程的阻塞,这对于锁竞争不激烈,且占用锁时间非常短的代码块来说,有较大的性能提升,因为自旋的消耗会小于线程阻塞挂起操作的消耗。 如果锁的竞争激烈,或者持有锁的线程需要长时间占用锁执行同步块,就不适合使用自旋锁了,因为自旋锁在获取锁前一直都是占用cpu做无用功,线程自旋的消耗大于线程阻塞挂起操作的消 耗,造成cpu的浪费。


在单核CPU上,自旋锁是无用,因为当自旋锁尝试获取锁不成功会一直尝试,这会一直占用CPU,其他线程不可能运行, 同时由于其他线程无法运行,所以当前线程无法释放锁。 混合型互斥锁, 在多核系统上起初表现的像自旋锁一样, 如果一个线程不能获取互斥锁, 它不会马上被切换为休眠状态,在一段时间依然无法获取锁,进行睡眠状态。
混合型自旋锁,起初表现的和正常自旋锁一样,如果无法获取互斥锁,它也许会放弃该线程的执行,并允许其他线程执行。 自旋锁只有在多核CPU上有效果,单核毫无效果,只是浪费时间。
 

3.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值