synchronized和lock

一、主要区别(表面)

    1.synchronized是java关键字;Lock是接口。 
    2.syn是通过JDK实现的,软件层依赖JVM锁定;Lock是硬件层通过CPU指令操作。 
    3.syn是隐式的获得、释放锁;Lock是显示的调用lock();unlock();在finally处必须手动释放,否则容易死锁。
    4.syn未拿到锁的线程只能干等(阻塞未释放锁时效率低);Lock具有可中段锁 tryLock(long,timeUnit)。 
    5.syn不知道当前线程有无获得锁;Lock可以通过tryLock()返回的bool值,知道有没有成功获得锁。
    6.sys不适用大量读操作(没必要的锁);Lock的实现类ReentrantReadWriteLock提供了readLock()和writeLock()用来获取读锁和写锁,读-读不互斥。
    7.syn可以锁代码块、对象实例(this)、类;Lock锁的范围只局限于代码块。
    8.both:可重入锁(嵌套锁直接获取); Lock only:可中段锁(等一会没拿到就中断)、公平锁(等得久先拿)、读写锁(读读不互斥)。
    9.synchronized和lock的底层区别

二、synchronized底层原理

    1.锁代码块时,对应位置字节码增加两个指令:monitorenter和monitorexit.。锁对象时,就在对象的[对象头]中的MarkWord部分进行一个标记。
    2.锁膨胀策略(1.6开始): 无锁状态  
        -> 偏向锁(假设拿锁的都是同一线程,再次获取就不用锁了:CAS操作)
        -> 轻量级锁,也叫乐观锁(此阶段竞争不激烈,自旋等待而不是直接挂起,减少线程上下文切换的消耗) 。
                        自旋锁/自适应自旋锁:自旋次数是否固定
        -> 重量级锁(上一阶段自旋超过10次就升级成重量级锁,后续所有的失败都直接挂起) ,也叫悲观锁、互斥锁。

三、ReentrantLock底层原理

    ReentrantLock是互斥锁,它是基于AQS实现的,AQS是Java并发包中众多同步组件的构建基础,它通过一个int类型的状态变量state(可重入)和一个FIFO队列(公平锁)来完成共享资源的获取,线程的排队等待等。加锁时将标志位state加1,释放锁时将state减1(加1减1的操作实现了可重入),通过compareAndSetState的cas原子操作修改state,自增成功说明当前线程拿到了锁。 cas机制可以说是concurrent包的基石了

四、死锁详解

    1.死锁的概念:两个或两个以上进程/线程,执行时由于竞争资源而产生互相等待的现象,若无外力作用,这些进程/线程都将无法向前推进。(过多的同步容易造成死锁)
    2.死锁的必要条件: a.互斥(一份资源每次只能被一个进程/线程使用)   b.请求与保持(进程/线程因请求资源而阻塞时,不释放已拥有的资源)   c.不剥夺(拥有的资源除非主动释放,不能强制剥夺)   d.循环等待(若干进程/线程的等待资源头尾相连)
    3.常见死锁: a.线程将自己锁住   b.多线程竞争资源时循环等待   c.进程推进顺序不当导致的死锁
    4.如果避免: a.合理分配资源,合理的进程推进顺序   b.尽量减少同步   c.使用可中段锁、可轮询的锁请求等   d.降低锁的粒度

五、悲观锁和乐观锁

    悲观锁:将资源锁住,等一个之前获得锁的线程释放锁之后,下一个线程才可以访问。
    乐观锁:每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败(内存和期望不相等,或者version不一样)就重试,直到成功为止。

    当有大量写操作/冲突严重时,适用悲观锁;少量写操作/冲突少时,适用乐观锁。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值