面试题之并发相关专栏一

一、Synchronized用过么?其原理是什么?

Synchronized是由JVM虚拟机实现的一种实现互斥同步的方式,被Synchronized修饰后的程序块编译后的字节码文件中,在编译前后被编译器生成了monitorenter和monitorexit两个字节码指令。

  • 在虚拟机执行到monitorenter指令时,首先要尝试获取对象的锁,如果这个对象没有锁定,或者当前线程已经拥有了这个对象的锁,把锁的计数器加1;
  • 当执行到monitorexit指令时将锁的计数器减1;
  • 当计数器为0时,锁就被释放了。如果获取对象失败了,那当前线程就要阻塞等待,一直到其他线程释放锁为止,Java中Synchronized是通过在对象头设置标记,达到了获取锁和释放锁的目的;

二、什么是可重入性,为什么说Synchronized是可重入锁?

可重入性是锁的一个基本要求,是为了解决自己锁死自己的情况。如果一个类中的同步方法method2调用另一个同步方法method1 ,假如 Synchronized 不支持重入,进入 method2 方法时当前线程获得锁,method2 方法里面执行 method1 时当前线程又要去尝试获取锁,对 Synchronized 来说,可重入性是显而易见的,在执行 monitorenter 指令时,如果这个对象没有锁定,或者当前线程已经拥有锁时如果不支持重入,它就要等其他线程释放锁,而把自己阻塞,导致自己锁死自己。有了这个对象的锁(而不是已拥有了锁则不能继续获取),就把锁的计数器 +1,其实本质上就通过这种方式实现了可重入性。

三、为什么说Synchronized是非公平锁?

非公平主要表现在获取锁的行为上,并非是按照申请锁的时间先后顺序给等待的线程分配锁资源,每当有线程使用锁后,由CPU调度,每一个线程都有机会竞争获取锁资源,包括刚刚释放锁的线程,也有可能再次获取这个锁对象,并不是队列中等待最久的线程就获取到锁。这样做的目的是为了提高执行性能,缺点就是可能会产生线程饥饿现象。

四、请谈谈可重入锁的原理?

每一个锁关联一个线程持有者和计数器。

  • 当计数器为 0 时表示该锁没有被任何线程持有,那么任何线程都可能获得该锁而调用相应的方法;
  • 当某一线程请求成功后,JVM会记下锁的持有线程,并且将计数器置为 1,此时如果其它线程请求锁资源,则必须阻塞等待;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增;当线程退出同步代码块时,计数器会递减,如果计数器为 0,则释放该锁。
发布了250 篇原创文章 · 获赞 112 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/Weixiaohuai/article/details/105331730