Java 中synchronized的知识点

1.Synchronized升级的原理是什么?

Synchronized锁升级原理:在锁对象里有一个threadid字段,在第一次访问的时候threadid为空,jvm让其持有偏向锁,并将threadid设置为其线程id,再次进入的时候会判段threadid 是否与其线程id一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级到重量级锁,此过程就构成了.Synchronized锁的升级。
锁升级的目的:锁升级是为了减低了锁带来的性能消耗。在Java6之后的优化.Synchronized的实现方式,使用了偏向锁升级为轻量锁在升级为重量锁的方式,从而减低了锁带来的性能消耗。

2.什么是死锁?

当线程A持有独占锁a,并尝试去获取锁b的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我么们称为死锁。

3.造成死锁的几个因素是什么(必须同时满足)?

1、互斥条件:任务使用的资源中至少有一个是不能共享的,资源的使用和释放方法都使用了synchronized关键字修饰
2、至少有一个任务它必须持有一个资源并且这个任务正在等待获取另一个当前正在被别的任务持有的资源
3、资源不能被项目抢占,任务必须把资源释放当做普通事件,资源只能被释放后才能被其他任务获取到
4、必须有循环等待,这时一个任务等待其他任务释放资源,其他任务又在等待另一个任务释放资源,且直到最后有一个任务在等待第一个任务释放资源,使得大家都被锁住,就造成了死锁

4.怎么预防死锁?

~尽量使用 tryLock(long,timeout,TimeUnit,unit)的方法(ReentrantLock,ReentrantReadWriteLock),设置超时时间,超时可以推出预防死锁。
~尽量使用java.util.concurrent并发类代替自己手写锁。
~尽量降低锁的使用粒度,尽量不要几个功能同用一把锁。
~尽量减少同步的代码块。

5.Java程序中怎么保证多线程运行安全?

方法一:使用安全类,比如Java.util.concurrent下的类。
方法二:使用自动锁synchronized。
方法三:使用手动锁Lock。

//手动锁Java示例代码:
Lock lock=new ReentrantLock();
lock.lock();
try{
   System.out.println("获得锁");   
}catch (Exception e){
     //TODO:habdle exception
}finally{
    System.out.println("释放锁");
    lock.unlock();
}

6.synchronized底层实现原理?

Synchronized是由一堆monitorenter/monitorexit指令实现的,monitor对象是同步的基本实现对象,在Java6之前,monitor的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态内核态的切换,所以同步操作是一个无差别的重量级操作,性能也很低。在Java6的时候,Java虚拟机对此进行了大刀阔斧的改进,提供了三种不同的Monitor的实现,也就是常说的三种不同锁:偏向锁(Biased
Locking),轻量级锁和重量级锁,大大的改进了其性能。

7.Synchronized和Lock的区别?

~.Synchronized可以给类,方法,代码块加锁;而lock只能给代码块加锁。
~.Synchronized不需要手动的获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;而lock需要自己加锁和释放锁,如果使用不当没有unlock()去释放锁就会造成死锁。
~通过lock可以知道有没有成功获取锁,而.Synchronized却无法办到。
1.synchronized是Java的关键字,当它用来修饰一-个synchronized是Java的关键字,当它用来修饰一-个方法或者一个代码块的时候,能够保证在同一时刻最多只有一-个线程执行该段代码。JDK1. 5以后引入了自旋锁、锁粗化、轻量级锁,偏向锁来有优化关键字的性能。
2.Lock是一-个接口,而synchronized是Java中的关键字,synchronized是内 置的语言实现; synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unL ock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁; synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;通过Lock可以知道有没有成功获取锁,而synchronized却无可以知道有没有成功获取锁,而synchronized却无法办到。

8.Syncronized锁,如果用这个关键字修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么?

synchronized修饰静态方法以及同步代码块的synchronized(类.class)用法锁的是类,线程想要执行对应同步代码,需要获得类锁。
synchronized修饰成员变量的方法,线程获取的是当前调用方法的对象实例的对象锁。

9.当一个线程进入对象的synchronized方法A之后,其它线程是否能进入此对象的synchronized方法B?

不能,其他的线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法上的synchronized修饰符要求执行方法时要获取对象的锁,如果已经进入A方法,说明对象锁已经被取走,那么试图进入B方法的线程只能在等锁池(注意不是等待池)中等待对象的锁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值