AQS介绍
AQS全称为(AbstractQueuedSynchronizer)抽象队列同步器这个类在java.util.concurrent.locks包下面。
AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构建出应用广泛的大量的同步器,比如我们提到的ReentrantLock,Semaphore,其他的诸如ReentrantReadWriteLock,SynchronousQueue,FutureTask等等皆是基于AQS的。当然,我们自己也能利用AQS非常轻松容易的构造出符合我们自己需求的同步器。
AQS原理分析
AQS核心思想就是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中
CLH队列是一个虚拟的双向队列,(虚拟的双向队列即不存在队列实例,仅存在节点之间的关联关系),AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node
)来实现锁的分配。
AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。AQS使用CAS对该
同步状态进行原子操作实现对其值的修改。
状态信息通过procted类型的getState,setState,compareAndSetState进行操作
AQS对资源的共享方式
AQS定义两种资源共享方式
Exclusive(独占): 只有一个线程能执行,如ReentrantLock。又可分为公平锁和非公平锁。
公平锁:按照线程在队列中的排队顺序,先到者先拿到锁
非公平锁:当线程要获取锁时,无视队列顺序直接去抢锁,谁抢到就是谁的
**Share(共享):**多个线程可同时执行,如Semaphore/CountDownLatch。Semaphore、
CountDownLatCh、 CyclicBarrier、ReadWriteLock 我们都会在后面讲到
ReentrantReadWriteLock可以看成是组合式,因为ReentrantReadWriteLock也就是读写锁允许多个线程同时对某一资源进行读。
不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队、唤醒出队等),AQS已经在顶层实现好了。
Java虚拟机
关于Java虚拟机,在面试的时候一般会问的大多就是Java内存区域,2虚拟机垃圾算法,3虚拟机垃圾收集器,4JVM内存管理,5JVM调优,6JAVA类加载机制这些问题了。
Java内存区域
介绍下Java内存区域(运行时数据区)
堆,栈,方法区,本地方法栈,程序计数器
Java对象的创建过程:
1,检查类是否被加载
2,为对象分配内存空间
3,为分配的内存空间初始化0值
4,对对象进行设置
5,执行构造方法
对象的访问定位的两种方式
句柄和直接指针两种方式
拓展问题
String类和常量池
String i = 1;此时1会直接被放入常量池
String i = new String(1);此时1在堆空间开辟空间后再指向常量池,new的底层就是通过反射来创建引用。
8种基本类型的包装类和常量池
Integer
character
Long
Short
Byte
Float
Double
Boolean
面试常见问题
如何判断对象是否死亡(两种方法)。
引用计数算法: 给对象添加一个引用计数器,每当有一个地方引用它的时候计数器加1,当引用失效时,就减1,当计数器为0时,对象便不可用。
优点:效率高
缺点:无法解决循环引用问题
根搜索算法:(JVM采用的算法)
设立若干种根对象,当任何一个根对象(GC Root)到某一个对象不可达时,则认为这个对象是可回收的。
简单的介绍一下强引用、软引用、弱引用、虚引用(虚引用与软引用和弱引用的区别、使用软引用能带来的好
处)。
强引用: 不会被回收
软引用: 当系统资源充足时不会回收,当系统资源不足时会被回收
弱引用: 当有GC回收时弱引用就会被回收
虚引用: 配合队列使用,通知机制
如何判断一个类是无用的类
1,该类所有的实例已经被回收,也就是java堆中不存在任何的实例
2,加载该类的ClassLoader已经被回收了
3,该类对应的java.lang.class对象,没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
垃圾收集有哪些算法,各自的特点?