Synchronized和Lock

SynchronizedLock
存在层次上是Java关键字,在jvm层面上处理是一个接口
锁的释放1.已经获取锁的线程执行完同步代码,释放锁. 2.线程执行发生异常,jvm会让线程释放锁在finally中必须手动释放锁,不然容易造成线程死锁
锁的获取假设A线程获得锁,B线程等待,如果A线程阻塞,B线程会一直等待有多个锁的获取方式,可以尝试获取锁,线程不用一直等待,用tryLock判断有没有锁
死锁产生异常会自动释放锁,不会有死锁异常不释放锁,需要手动unlock释放锁,可能会引起死锁
锁的状态无法判断状态可以判断状态
锁的类型可重入,不可中断,非公平锁可重入,可判断,可公平(两者皆可)
性能少量同步大量同步
调度使用object对象本身的wait、notify、notifyAll调度机制可以使用Condition进行线程之间的调度
用法需要在同步对象中加入此控制,可加在方法上,特定的代码块中,括号中表示需要锁得对象一般使用ReentrantLock类作为锁,在加锁和解锁处要使用lock()和unlock()进行指出,所以一般会在finally块中写unlock()以防死锁
底层实现底层使用指令码方式来控制锁的,映射成字节码指令就是增加来两个指令:monitorenter和monitorexit。当线程执行遇到monitorenter指令时会尝试获取内置锁,如果获取锁则锁计数器+1,如果没有获取锁则阻塞;当遇到monitorexit指令时锁计数器-1,如果计数器为0则释放锁底层是CAS乐观锁,依赖AbstractQueuedSynchronizer类,把所有的请求线程构成一个CLH队列。而对该队列的操作均通过Lock-Free(CAS)操作

synchronized的缺陷,Java Lock如何处理?

synchronized的缺陷

效率低:锁的释放情况很少,只有代码执行完毕或者异常结束才会释放试图获取所得时候不能设置超时,不能中断一个正在使用锁的线程,相对而言,Lock可以中断和设置超时。
不够灵活:加锁和释放锁的时机单一,每个锁仅有一个单一的条件(某个对象),相对而言,读写锁更加灵活
无法知道是否成功获得锁:无法判断状态

Lock的处理

主要方法:
1.lock()加锁
2.unlock()解锁
3.tryLock() 尝试获取锁,返回一个Boolean值
4.tryLock()尝试获取锁,可设置超市时间

Synchronized只有锁只与一个条件(是否获取锁)相关联,不灵活,后来Condition与Lock的结合解决了这个问题。

多线程竞争一个锁时,其余未得到锁的线程只能不停的尝试获得锁,而不能中断。高并发的情况下会导致性能下降。ReentrantLock的lockInterruptibIy()方法可以优先考虑响应中断。一个线程等待时间过长,它可以中断自己,然后ReentrantLock响应这个中断,不再让这个线程继续等待。有了这个机制,使用ReentrantLock时就不会像Synchronized那样产生死锁了。

学习笔记欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值