1.ReentrantLock中tryLock()和lock()方法的区别
- tryLock()表示尝试加锁,可能加到,也可能加不到,该方法不会阻塞线程,如果加到锁则返回true,没有加到则返回false
- lock()表示阻塞加锁,线程会阻塞直到加到锁,方法也没有返回值
2.Sychronized的偏向锁、轻量级锁、重量级锁
- 偏向锁:在锁对象的对象头中记录一下当前获取到该锁的线程ID,该线程下次如果又来获取该锁就可以直接获取到了
- 轻量级锁:由偏向锁升级而来,当一个线程获取到锁后,此时这把锁是偏向锁,此时如果有第二个线程来竞争锁,偏向锁就会升级为轻量级锁,之所以叫轻量级锁,是为了和重量级锁区分开来,轻量级锁底层是通过自旋来实现的,并不会阻塞线程
- 如果自旋次数过多仍然没有获取到锁,则会升级为重量级锁,重量级锁会导致线程阻塞
- 自旋锁:自旋锁就是线程在获取锁的过程中,不会去阻塞线程,也就无所谓唤醒线程,阻塞和唤醒这两个步骤都是需要操作系统去进行的,比较消耗时间,自旋锁是线程通过CAS获取预期的一个标记,如果没有获取到,则继续循环获取,如果获取到了则表示获取到了锁,这个过程线程一直在运行中,相对而言没有使用太多的操作系统资源,比较轻量。
3.Sychronized和ReentrantLock的区别
- sychronized是一个关键字,ReentrantLock是一个类
- sychronized会自动的加锁与释放锁,ReentrantLock需要程序员手动加锁与释放锁
- sychronized的底层是JVM层面的锁,ReentrantLock是API层面的锁
- sychronized是非公平锁,ReentrantLock可以选择公平锁或非公平锁
- sychronized锁的是对象,锁信息保存在对象头中,ReentrantLock通过代码中int类型的state标识来标识锁的状态
- sychronized底层有一个锁升级的过程
4.谈谈你对AQS的理解,AQS如何实现可重入锁?
- AQS是一个JAVA线程同步的框架。是JDK中很多锁工具的核心实现框架。
- 在AQS中,维护了一个信号量state和一个线程组成的双向链表队列。其中,这个线程队列,就是用来给线程排队的,而state就像是一个红绿灯,用来控制线程排队或者放行的。 在不同的场景下,有不用的意义。
- 在可重入锁这个场景下,state就用来表示加锁的次数。0标识无锁,每加一次锁,state就加1。释放锁state就减1。
5.谈谈你对IOC的理解
通常,我们认为Spring有两大特性IoC和AOP,那到底该如何理解IoC呢?
对于很多初学者来说,IoC这个概念给人的感觉就是我好像会,但是我说不出来。
那么IoC到底是什么,接下来来说说我的理解,实际上这是一个非常大的问题,所以我们就把它拆细了来回答,IoC表示控制反转,那么:
- 什么是控制?控制了什么?
- 什么是反转?反转之前是谁控制的?反转之后是谁控制的?如何控制的?
- 为什么要反转?反转之前有什么问题?反转之后有什么好处?
这就是解决这一类大问题的思路,大而化小。
那么,我们先来解决第一个问题:什么是控制?控制了什么?
我们在用Spring的时候,我们需要做什么:
- 建一些类,比如UserService、OrderService
- 用一些注解,比如@Autowired
但是,我们也知道,当程序运行时,用的是具体的UserService对象、OrderService对象,那这些对象是什么时候创建的?谁创建的?包括对象里的属性是什么时候赋的值?谁赋的?所有这些都是我们程序员做的,以为我们只是写了类而已,所有的这些都是Spring做的,它才是幕后黑手。
这就是控制:
- 控制对象的创建
- 控制对象内属性的赋值
如果我们不用Spring,那我们得自己来做这两件事,反过来,我们用Spring,这两件事情就不用我们做了,我们要做的仅仅是定义类,以及定义哪些属性需要Spring来赋值(比如某个属性上加@Autowired),而这其实就是第二个问题的答案,这就是反转,表示一种对象控制权的转移。
那反转有什么用,为什么要反转?
如果我们自己来负责创建对象,自己来给对象中的属性赋值,会出现什么情况?
比如,现在有三个类:
- A类,A类里有一个属性C c;
- B类,B类里也有一个属性C c;
- C类
现在程序要运行,这三个类的对象都需要创建出来,并且相应的属性都需要有值,那么除开定义这三个类之外,我们还得写:
- A a = new A();
- B b = new B();
- C c = new C();
- a.c = c;
- b.c = c;
这五行代码是不用Spring的情况下多出来的代码,而且,如果类在多一些,类中的属性在多一些,那相应的代码会更多,而且代码会更复杂。所以我们可以发现,我们自己来控制比交给Spring来控制,我们的代码量以及代码复杂度是要高很多的,反言之,将对象交给Spring来控制,减轻了程序员的负担。
总结一下,IoC表示控制反转,表示如果用Spring,那么Spring会负责来创建对象,以及给对象内的属性赋值,也就是如果用Spring,那么对象的控制权会转交给Spring。
6.单例Bean和单例模式
单例模式表示JVM中某个类的对象只会存在唯一一个。
而单例Bean并不表示JVM中只能存在唯一的某个类的Bean对象。
7.Spring事务传播机制
多个事务方法相互调用时,事务如何在这些方法间传播,方法A是一个事务的方法,方法A执行过程中调用了方法B,那么方法B有无事务以及方法B对事务的要求不同都会对方法A的事务具体执行造成影响,同时方法A的事务对方法B的事务执行也有影响,这种影响具体是什么就由两个方法所定义的事务传播类型所决定。
- REQUIRED(Spring默认的事务传播类型):如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务
- SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
- MANDATORY:当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。
- REQUIRES_NEW:创建一个新事务,如果存在当前事务,则挂起该事务。
- NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务
- NEVER:不使用事务,如果当前事务存在,则抛出异常
- NESTED:如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样(开启一个事务)