JAVA
类加载器
- 根类加载器:jre/lib
- 扩展类加载器:jre/lib/ext扩展类库
- 应用类加载器:用户自己定义的类
双亲委派模型
- 调用类加载器的LoadClass方法进行类加载时(需要加锁synchronized),该类加载器会首先请求父类加载器,依次递归,如果所有的父类加载器都加载失败,则当前类加载器自己进行加载操作(避免用户自定义的类覆盖核心类库),如果找不到抛出NoSuchClass异常
- 如果需要实现自己的类加载器且不破坏双亲委派模型,需要继承ClassLoader类并重写findClass方法,如果需要破坏双亲委派模型,则重写loadClass方法
- loadClass的逻辑里如果父类加载器加载失败会调用findClass方法完成加载
protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
IO:同步,阻塞
NIO:同步非阻塞Channel:流
Buffer:从流中读写数据
Selector:注册到很多个Channel上,监听每个Channel上发生的事件,根据情况决定Channel的读写,可以通过一个线程管理多个Channel
阻塞模式下注册操作不允许
AIO:异步,非阻塞
IO操作完成以后再给线程发送通知。
红黑树和平衡二叉树的区别
- 平衡二叉树左右子树高度差不超过1,是严格的平衡二叉树,适合插入删除少但查找多的情况
- 红黑树是弱平衡二叉树,高度一般不小于平衡二叉树,适合搜索插入删除操作的情况下,根节点到叶子节点的最长路径不多于最短路径的两倍,插入删除查找复杂度都是O(logN),最多3次旋转能够达到平衡*,
避免死锁的集中2方式
- 设置加锁顺序
- 设置加锁时限,超时不再获取锁
- 死锁检测:
死锁存在条件
- 互斥条件:一个资源每次只能被一个进程使用,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
- 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
- 不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
- 循环等待条件: 若干进程间形成首尾相接循环等待资源的关系
Java8 default static特性-接口使用
- java使用default修饰接口就可以有默认实现
- 新注解 @FunctionalInterface 表明该接口是一个函数式接口,只能拥有 一个抽象方法。
- 必须要有具体的实现
锁
线程执行到临界区的时候,会利用CAS将线程ID插入到Markword中,同时修改偏向锁的标志位(会在对象头和栈中的锁记录里存储偏向的线程ID)
CAS是乐观锁机制,读数据不加锁,写数据加锁,比较原值是否修改,ABA问题:版本号
锁只能升级不能降级
- 锁膨胀:两个线程竞争时,偏向锁会失效,升级为轻量级锁
-
轻量级锁:乐观锁
- 自旋锁:当有另外一个线程来竞争锁时,这个线程会原地等待,而不是把该线程阻塞,直到获得锁的线程释放锁之后立即获得锁(消耗CPU)
- 自适应锁:动态根据实际情况改变自旋锁的等待次数,刚刚获得锁的线程会增加自旋次数,很长时间没有获得锁的自旋次数会减少直至升级为重量级锁
- 偏向锁:锁会偏向于第一个获得它的线程,没有其他线程竞争则不会进行同步操作
- 偏向锁失效,会撤销锁,需要等待全局安全点,-XX:-UseBiasedLocking=false关闭偏向锁
- 重量级锁:轻量级锁膨胀之后会升级为重量级锁(互斥锁),会阻塞线程,唤起线程需要消耗资源(阻塞同步)
网友评论