1.异常结构图

  1.异常分类:

    优秀原文链接:https://www.cnblogs.com/hysum/p/7112011.html

    1.都继承Throwable,分为error和exception.

      1.error:包括虚拟机错误和线程死锁,一旦Error出现了,程序就彻底的挂了,被称为程序终结者;

      2.exception:也就是通常所说的“异常”。主要指编码、环境、用户操作输入出现问题,Exception主要包括两大类,非检查异常(RuntimeException)和检查异常(其他的一些异常)。

        1.检查异常:

          1.引起该异常的原因多种多样,比如说文件不存在、或者是连接错误等等。

          2.该异常我们必须手动在代码里添加捕获语句来处理该异常,也是我们学习java异常语句中主要处理的异常。

          3.throw和throws关键字:

            1.throw ----将产生的异常抛出,是抛出异常的一个动作。而throw出现在函数体。

            2.throws----声明将要抛出何种类型的异常(声明),throws出现在方法函数头。

        2.非检查异常:

          主要包括以下四种异常

          1.空指针异常、

          2.数组下标越界异常、

          3.类型转换异常、

          4.算术异常

  

  2.自定义异常:

    1.为什么要用自定义异常,有什么用?使用自定义异常要权衡,是否需要。

      1.项目是分模块或者分功能开发的 ,基本不会你一个人开发一整个项目,使用自定义异常类就统一了对外异常展示的方式

      2.自定义异常可以在我们项目中某些特殊的业务逻辑时抛出异常。

      3.使用自定义异常继承相关的异常来抛出处理后的异常信息可以隐藏底层的异常,这样更安全,异常信息也更加的直观。

    2.在 Java 中自定义异常。编写自己的异常类时需要记住下面的几点:

      1.所有异常都必须是 Throwable 的子类。

      2.如果希望写一个检查性异常类,则需要继承 Exception 类。

      3.如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

  3.Java中的异常链:异常需要封装,但是仅仅封装还是不够的,还需要传递异常

    1.描述:异常链是一种面向对象编程技术,指将捕获的异常包装进一个新的异常中并重新抛出的异常处理方式。

    2.initCause()的作用是包装原始的异常,当想要知道底层发生了什么异常的时候调用getCause()就能获得原始异常。 

    3.这样做的意义是一个方法应该抛出定义在相同的抽象层次上的异常,但不会丢弃更低层次的信息。

  4.良好的编码习惯:

    1、处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理

    2、在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常

    3、对于不确定的代码,也可以加上try-catch,处理潜在的异常

    4、尽量去处理异常,切记只是简单的调用printStackTrace()去打印

    5、具体如何处理异常,要根据不同的业务需求和异常类型去决定

    6、尽量添加finally语句块去释放占用的资源

    7、异常需要封装和传递,我们在进行系统开发的时候,不要“吞噬”异常,也不要“赤裸裸”的抛出异常,封装后在抛出,或者通过异常链传递,可以达到系统更健壮、友好的目的。

1.jdk包下工具类及原理

  1.hashMap底层实现原理:

    1.底层存储,如何put,get,remove.如何扩容,缩容

  2.synchronized和lock的区别

    1.synchronized:

      1.普通同步方法,锁是当前实例对象

      2.静态同步方法,锁是当前类的class对象

      3.同步方法块,锁是括号里面的对象

    2.synchronized实现原理:

      1.同步代码块

        使用monitorenter和monitorexit指令实现的。

      2.同步方法

        (在这看不出来需要看JVM底层实现)依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。

      3.Mark Word

        1.在默认情况下存储着对象的HashCode、分代年龄、锁标记位等

        以下是32位JVM的Mark Word默认存储结构

        

        2.JVM的空间效率,Mark Word 被设计成为一个非固定的数据结构

        

 

 

       4.jvm对synchorized的优化:https://cloud.tencent.com/developer/article/1031633

        优秀原文:https://www.cnblogs.com/aspirant/p/11470858.html

        1.优化:

          1.增加的锁:增加了自适应的CAS自旋、锁消除、锁粗化、偏向锁、轻量级锁这些优化策略。          

          2.锁的状态总共有四种:无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁,但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级。

        2.自旋锁:

          1.线程的阻塞和唤醒需要CPU从用户态转为核心态,频繁的阻塞和唤醒对CPU来说是一件负担很重的工作。CAS,通过参数设置自旋次数。

        3.适应性自旋锁:

          1.线程如果自旋成功了,那么下次自旋的次数会更加多,因为虚拟机认为既然上次成功了,那么此次自旋也很有可能会再次成功,那么它就会允许自旋等待持续的次数更多。

          2.反之,如果对于某个锁,很少有自旋能够成功,那么在以后要或者这个锁的时候自旋的次数会减少甚至省略掉自旋过程,以免浪费处理器资源。

        4.锁消除:

          1.在操作操作同步控制时,是为了保证数据完整性,但在有些情况下,JVM检测到不可能存在共享数据竞争,这时JVM会对这些同步锁进行锁消除。

 

 

         5.偏向锁:

          1.在大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低,引进了偏向锁。

          2.偏向锁的释放采用了 一种只有竞争才会释放锁的机制,线程是不会主动去释放偏向锁,需要等待其他线程来竞争。

          3.偏向锁获取释放过程:

          

        6.轻量级锁:

          1.引入轻量级锁的主要目的是 在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。

          2.轻量级锁的获取和释放过程:

            1.为什么升级为轻量锁时要把对象头里的Mark Word复制到线程栈的锁记录中呢?

              1.因为在申请对象锁时 需要以该值作为CAS的比较条件,同时在升级到重量级锁的时候,能通过这个比较判定是否在持有锁的过程中此锁被其他线程申请过,如果被其他线程申请了,则在释放锁的时候要唤醒被挂起的线程。

            2.为什么会尝试CAS不成功以及什么情况下会不成功?

              1.CAS本身是不带锁机制的,其是通过比较而来。假设如下场景:线程A和线程B都在对象头里的锁标识为无锁状态进入,那么如线程A先更新对象头为其锁记录指针成功之后,线程B再用CAS去更新,就会发现此时的对象头已经不是其操作前的对象HashCode了,所以CAS会失败。也就是说,只有两个线程并发申请锁的时候会发生CAS失败。

              2.然后线程B进行CAS自旋,等待对象头的锁标识重新变回无锁状态或对象头内容等于对象HashCode(因为这是线程B做CAS操作前的值),这也就意味着线程A执行结束(参见后面轻量级锁的撤销,只有线程A执行完毕撤销锁了才会重置对象头),此时线程B的CAS操作终于成功了,于是线程B获得了锁以及执行同步代码的权限。如果线程A的执行时间较长,线程B经过若干次CAS时钟没有成功,则锁膨胀为重量级锁,即线程B被挂起阻塞、等待重新调度。

        7.重量级锁:

 

           1.Synchronized是通过对象内部的一个叫做 监视器锁(Monitor)来实现的。

          2.但是监视器锁本质又是依赖于底层的操作系统的Mutex Lock来实现的。

          3.而操作系统实现线程之间的切换这就需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么Synchronized效率低的原因。

          4.因此,这种依赖于操作系统Mutex Lock所实现的锁我们称之为 “重量级锁”。

        8.状态转换图:

          

 

 

    3.lock实现原理:略

    4.区别