Java一些基础知识

JAVA

类加载器

  1. 根类加载器:jre/lib
  2. 扩展类加载器:jre/lib/ext扩展类库
  3. 应用类加载器:用户自己定义的类

双亲委派模型

  • 调用类加载器的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方式

  1. 设置加锁顺序
  2. 设置加锁时限,超时不再获取锁
  3. 死锁检测:

死锁存在条件

  1. 互斥条件:一个资源每次只能被一个进程使用,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
  2. 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
  3. 不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
  4. 循环等待条件: 若干进程间形成首尾相接循环等待资源的关系

Java8 default static特性-接口使用

  • java使用default修饰接口就可以有默认实现
  • 新注解 @FunctionalInterface 表明该接口是一个函数式接口,只能拥有 一个抽象方法。
  • 必须要有具体的实现

线程执行到临界区的时候,会利用CAS将线程ID插入到Markword中,同时修改偏向锁的标志位(会在对象头和栈中的锁记录里存储偏向的线程ID)
CAS是乐观锁机制,读数据不加锁,写数据加锁,比较原值是否修改,ABA问题:版本号
锁只能升级不能降级

  • 锁膨胀:两个线程竞争时,偏向锁会失效,升级为轻量级锁
  • 轻量级锁:乐观锁
    • 自旋锁:当有另外一个线程来竞争锁时,这个线程会原地等待,而不是把该线程阻塞,直到获得锁的线程释放锁之后立即获得锁(消耗CPU)
    • 自适应锁:动态根据实际情况改变自旋锁的等待次数,刚刚获得锁的线程会增加自旋次数,很长时间没有获得锁的自旋次数会减少直至升级为重量级锁
  • 偏向锁:锁会偏向于第一个获得它的线程,没有其他线程竞争则不会进行同步操作
  • 偏向锁失效,会撤销锁,需要等待全局安全点,-XX:-UseBiasedLocking=false关闭偏向锁
  • 重量级锁:轻量级锁膨胀之后会升级为重量级锁(互斥锁),会阻塞线程,唤起线程需要消耗资源(阻塞同步)

你可能感兴趣的:(Java一些基础知识)