多线程--对象锁与类锁的区别

多线程--对象锁与类锁的区别

对象锁

对象锁:java中任何对象都拥有一个互斥锁,当一个类中声明了synchronized方法,或者在方法中声明了参考(reference)对象为this的synchronized代码块
则表示在此方法或者此代码块中该对象同时只能被同一个线程访问。
例如类A有一个同步方法f1(),a1、a2两个实例对象
当一个线程t1通过a1调用f1()时,此时t1拥有对象a1的锁,与此同时:
1.当其他线程再次通过a1来调用f1时,此时需要等待t1将a1的锁释放才能进入,此时为阻塞状态。
2.当线程t2通过a2来调用f1()时,是不会阻塞的,因为t1只是持有了a1的锁并没有持有a2的锁。

类锁

类锁:java中类的所有实例化对象都属于该类的class对象,当一个类中,拥有同步静态方法,或者同步代码块使用类名.class修饰,那么当前类只能同时被一个对象持有类锁。此时该类的静态成员,静态方法,因为都从属于该类,所有只能同时被一个该类实例对象访问。

由于一个class不论被实例化多少次,其中的静态方法和静态变量在内存中都只有一份。所以,一旦一个静态的方法被申明为synchronized。此类所有的实例化对象在调用此方法,共用同一把锁,我们称之为类锁。

小结

对象锁用来控制实例方法之间的同步,类锁是用来控制静态方法(或静态变量互斥体)之间的同步。
 
对于类锁,会把整个类锁住,也就说只能有一个对象拥有当前类的锁。当一个对象拥有了类锁之后,另外一个对象还想竞争锁的话则会被阻塞。
两个对象A,B,如果A正在访问一个被类锁修饰的方法function,那么B则不能访问。因为类锁只能在同一时刻被一个对象拥有。相对于对象锁,则不同:还是A,B两个对象,如果A正在访问对象锁修饰的function,那么这个时候B也可以同时访问。

对象锁(方法锁),是针对一个对象的,它只在该对象的某个内存位置声明一个标识该对象是否拥有锁,所以它只会锁住当前的对象,一般一个对象锁是对一个非静态成员变量进行synchronized修饰,或者对一个非静态成员方法进行synchronized进行修饰,对于对象锁,不同对象访问同一个被synchronized修饰的方法的时候不会阻塞

拓展–可重入锁

可重入锁:对于对象锁,当一个对象拥有锁之后,访问一个加了对象锁的方法,而该方法中又调用了该类中其他加了对象锁的方法,那么这个时候是不会阻塞住的。

这是java通过可重入锁机制实现的。可重入锁指的是当一个对象拥有对象锁之后,可以重复获取该锁。因为synchronized块是可重入的,所以当你访问一个对象锁的方法的时候,在该方法中继续访问其他对象锁方法是不会被阻塞的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hongmin.shm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值