java EE学习总结 第六周(包含思维导图)

第六周

Day26

异常

  • 异常的概念

    • 异常在运行过程中出现特殊的情况
    • 异常处理的必要性:任何程序都可能存在大量的未知问题、错误;如果不对这些问题进行正确的处理,则可能导致程序的中断,造成不必要的损失
  • 异常的分类

    • Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中。
    • -Error:JVM 、硬件、执行逻辑错误,不能手动处理
    • Exception:程序在运行和配置中产生的问题,可处理
    • RuntimeException:运行时异常,可处理,可不处理
    • CheckedException:受查异常,必须处理
  • 异常 的产生

    • 自动抛出异常:当程序值在运行时遇到不规范的代码或结果时,会产生异常
    • 手动抛出异常:语法:throws new 异常类型(“实际参数”)
    • 产生异常结果:相当于遇到return 语句。导致程序因异常而终止
  • 异常的传递

    • 概念:按照方法的调用链反向传递。如果始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)
    • 受查异常: throws 声明异常吧,修饰在方法参数列表后端
    • 运行时异常:因可处理可不处理。无需声明异常
  • 异常的处理

    try {

    可能出现异常的代码

    }catch(Exception e ){
    异常处理的相关代码,如 :getMessage()、printStackTrace()

    }finally{

    无论是否出现异常,都需执行的代码结构,常用于释放资源

    }

    • 常见异常处理结构

      • try{} catch {}
      • try{} catch{}catch{}
      • try{} catch{}finally{}
      • try{}catch{}catch{] finally{}
      • try{} finally
      • 注意:多重catch,遵循从子(小)到父(大)的顺序,父类异常在最后
  • 自定义异常

    • 需继承自ERxception 或Exception 的子类,常用RuntimeException

    • 必要提供的构造方法

      • 无参数构造方法
      • String message参数的构造方法
  • 方法的覆盖

    • 带有异常声明的方法覆盖

      • 方法名、参数列表、返回值类型必须和父类相同
      • 子类的访问修饰符合父类相同或是比父类更宽
      • 子类中的方法,不能抛出比父类更多、更宽的异常
  • 总结

    • 异常的概念:程序在运行过程中出现的特殊情况

    • 异常的分类

      • RuntimeException:运行时异常、可处理、可不处理
      • CheckedException:受查异常,必须处理
    • 异常的产生

      • throw new 异常类型(“实际参数”)
      • 相当于遇到return 语句,导致程序因异常而终止
    • 异常的传递

      • 按照方法的调用链反向传递,如始终没有处理异常,最终会由jvm 进行默认异常处理(打印堆栈跟踪信息)
    • 异常的处理

      • try{} catch{} finally{}
    • 带有异常声明的方法覆盖:

      • 子类中的方法,不能抛出比父类更多、更宽的异常

Day27、Day28

多线程

  • 线程的概念

    • 运行时的程序,才被称为进程
    • 线程,又轻量级进程。程序中的一个顺序控制流程,同时也是CPU的基本调度单位。进程由多个线程组成,彼此间完成不同的工作,交替执行,称为多线程
  • 线程的组成

    • 任何一个线程都具有基本的组成部分

    • CPU时间片:操作系统会为每个线程分配执行时间

    • 运行数据:

      • 堆空间:存储线程需使用的对象,多个线程可以共享堆中的对象
      • 栈空间:存储线程需使用的局部变量,每个线程都拥有独立的栈
    • 逻辑代码

  • 创建线程的方式

    • 创建线程的第一种方式

      public class TestCreateThread {
      public static void main(String[] args){
      MyThread t1 = new MyThread();
      t1.start();

      }

      }

      class MyThread extends Thread{
      public void run(){
      for (int i = 1;i<=50;i++){

              System.out.println("MyThread:L"+i);
      

      }

      }

      }

    • 创建线程的第二种方式:

      public class TestCreateThread{
      public static void main(String [] args){

      MyRunnable mr = new MyRunnable();
      Thread t2 = new Thread(mr);
      t2.start();

      }
      }

      class MyRunnale implements Runnnale {

       public void  run (){
      
           for (int i = 1;i<=50;i++){
          System.out.println("MyRunnale:"+i);
      

      }
      }
      }

  • 线程的状态

    • New 初始状态

      • 线程对象被创建,即为初始状态。只在堆中开辟内存,与常规对象无异
    • Ready就绪状态

      • 调用start()之后,进入就绪状态。等待OS选中,并分配时间片
    • Running 运行状态

      • 获得时间片之后,进入运行状态,如果时间片到期,则返回到就绪状态
    • Terminated终止状态

      • 主线程main()或独立线程run()结束,进入终止状态, 并释放持有的时间片
  • 常见方法

    • 休眠

      • public static void sleep(long millis)
      • 当前线程主动休眠millis毫秒
    • 放弃

      • public static void yield
      • 当前线程主动放弃时间片,回到就绪状态你,竞争下一次时间片
    • 结合

      • public final void join()
      • 允许其他线程加入到当前线程中
  • 线程的安全

    • 需求

      • A线程将“HeLlo”存入数组的第一空位;B线程将“world”存入数组的第一个空位
    • 线程不安全

      • 当多线程并发访问临界资源时,如果破坏原子操作,可能会造成数据不一致
      • 临界资源:共享资源(同一对象),一次仅允许一个线程使用,才可保证其正确性
      • 原子操作:不可分割的多步操作,被视作一个整体,其顺序和步骤不可打乱或缺省
  • 同步方式

    • 同步代码块

      synchronized (临界资源对象){//对临界资源对象加锁

      // 代码(原子操作)

      }

    • 注意

      • 每个对象都有一个互斥锁标的标记,用来分配给线程的
      • 只有拥有对象互斥锁标记的线程,才能进入对该对象加锁的同步代码块
      • 线程退出同步代码块时,会释放相应的互斥锁标记
  • 同步方式2

    • 同步方法

      synchronized 返回值类型 方法名称(形参列表()){// 对当前对象(this)加锁

      //代码(原子操作)

      }

      • 只有拥有对象互斥锁标记的线程,才能进入该对象加锁的同步方法中
      • 线程退出同步方法时,会释放相应的互斥锁标记
  • 同步规则

    • 注意

      • 只有在调用包含同步代码的方法,或者同步方法时,才需要对象的锁标记
      • 如调用不包含同步代码块的方法,或普通方法时,则不需要锁标记,可直接调用
    • 已知jdk 中线程安全的类

      • StringBuffer
      • Vector
      • Hashtable
      • 以上的类中的公开方法,均为synchonized修饰的同步方法
  • 经典问题

    • 死锁

      • 当第一个线程拥有A对象锁标记。并等待B对象锁标记,同时第二个线程拥有B对象锁标记,并等待 A 对象锁标记时,产生死锁
      • 一个线程可以同时拥有多个对象的锁标记,当线程阻塞时,不会释放已经拥有的锁标记,由此可能造成死锁
    • 生产者、消费者

      • 若干个生产者在生产产品,这些产品将提供若干消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个能存储多个产品的缓冲区,生产者将生产的产品放入缓冲区中,消费者从缓冲区中取走产品进行消费,显然生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个慢的缓冲区中放入产品
  • 线程通信

    • 等待

      • public final void wait()
      • public final void wait(long timeout)
      • 必须在对obj 加锁的同步代码块中。在一个线程中,调用obj.wait() 时。此线程会释放其拥有的所有锁标记。同时此线程阻塞在o 的等待队列中。释放 锁,进入等待队列
    • 通知

      • public final void notify()
      • public final void notifyAll()
      • 必须在对obj 加锁的同步代码块中。从obj 的Wating中释放一个或全部线程。对自身没有任何影响
  • 总结

    • 线程的创建

      • 方式1:继承Thread类
      • 方式2:实现Runnable 接口(一个任务Task),传入给Thread对象并执行
    • 线程安全

      • 同步代码块:为方法中的局部代码(原子操作)加锁
      • 同步方法:为方法中的所有代码(原子操作)加锁
    • 线程间的通信:

      • wait(0 /wait(long timeout) 等待
      • notify()/notifyAll():通知
  • 线程池

    • 现有问题

      • 线程是宝贵的内存资源、单个线程约占1MB空间,过分分配易造成内存溢出。
      • 频繁的创建及销毁线程会增加虚拟机回收效率、资源开销,造成程序性能下降
    • 线程池

      • 线程容器,可设定线程分配的数量上限
      • 将预先创建的线程对象存入池中,并重用线程池中的线程对象
      • 避免频繁的创建和销毁
  • 线程池原理

    • 将任务提交给线程池,由线程池分配线程、运行任务,并在当前任务结束后复用线程
  • 获取线程池

    • 常用的线程池接口和类(所在包java.util.concurrent)
    • Executor:线程池的顶级接口
    • ExecutorService:线程池接口,可通过submit(Runnale task )提交任务代码
    • Executors工厂类:通过此类可以获得此类可以获得一个线程池
    • 通过newFixedThreadPool(int nThreads)获取固定数量的线程池。参数:指定线程池中线程的数量
    • 通过newCachedThreadPool() 获取动态数量的线程池,如不够则创建新的,没有上限
  • Callable接口

    public interface Callable{

    public V call () throws Exception;

    }

    • JDK5加入,与Runnale 接口类似,实现之后代表一个线程任务
    • Callable具有泛型返回值、可以声明异常
  • Future 接口

    • 概念:异步接收ExecutorService.submit()所返回的状态结果,当中包含了call() 返回值
    • 方法: V get() 以阻塞形式等待Future中的异步处理结果(call() 的返回值)
  • 线程的同步

    • 形容一次方法调用,同步一旦开始。调用者必须等待该方法返回,才能继续
    • 注意:单条路径
  • 线程的异步

    • 形容一次方法调用,异步一旦开始,像是一次消息传递,调用者告知之后立刻返回,二者竞争时间片,并发执行
    • 注意:多条执行路径
  • Lock接口

    • jdk5 加入,与synchronized 比较,显示定义,结构更灵活

    • 提供更多实用性方法,功能更强大、性能更优越

    • 常用方法

      • void lock() // 获取锁,如锁被占用。则等待
      • boolean tryLock() //尝试获取锁(成功返回true。失败返回false ,不阻塞)
      • void unlocck() // 释放锁
  • 重入锁

    • ReentrantLock:Lock接口的实现类,与synchronized 一样具有互斥锁功能
  • 读写锁

    • ReentrantReadWriteLock

      • 一种支持一写多读的同步锁,读写分离,可分别分配读锁,写锁
      • 支持多次分配读锁,使多个读操作可以并发执行
    • 互斥规则

      • 写-写:

        • 互斥,阻塞
      • 读-写

        • 互斥,读阻塞写,写阻塞读
      • 读-读

        • 不互斥、不阻塞
      • 在读操作远远高于写操作的环境中,可保障线程安全的情况下,提高运行效率

day29,day30

<爱编码的程序员> 这个微信公众号有更多关于java知识的详解

I/O 框架部分

  • 流的概念

    • 内存与存储设备之间传输数据的通道
  • 流的分类

    • 按方向

      • 输入流:

        • 将<存储设备 >中的内容读入到<内存>中
      • 输出流

        • 将<内存>中的内容写入到<存储设备>中
    • 按单位

      • 字符流

        • 以字符为单位,只能读写文本数据
      • 字节流

        • 以字节为单位,可以读写所有数据
    • 按功能

      • 节点流

        • 具有实际传输数据的读写功能
      • 过滤流

        • 在节点流的基础之上增强功能
  • 字节流

    • 字节流的父类(抽象类)

    • InputSteam:字节输入流

      • public int read()[]
      • public int read(byte[] b){}
      • public int read(byte[] b ,int off ,int len){}
    • outputStream:字节输出流

      • public void write(int n){}
      • public void write(byte[] b ){}
      • public void write(byte[] b ,int off,int len){}
  • 编码方法

  • 字符流

  • File类

在这里插入图片描述

发布了32 篇原创文章 · 获赞 9 · 访问量 3137

猜你喜欢

转载自blog.csdn.net/weixin_43501566/article/details/104908088