A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© dyynrahbsqt 中级黑马   /  2018-11-20 15:53  /  635 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

day05  异常 多线程
异常的分类
// 异常的体系结构
java.lang.Throwable  // 体系最顶层
        |_ Error                  // 错误
        |_ Exception              // 编译时异常
                |_ RuntimeException   // 运行时异常
错误(Error): 不能捕获处理的严重问题. 绝症
        必须将程序停下来, 修改代码才能解决
        错误的类名都是 "XxxError" 方式
异常(Exception): 可以捕获处理的问题. 发烧感冒吃个药就好了
        程序执行起来后, 如果有合适的处理方式, 即使发生异常, 程序也能处理该异常并继续运行
        异常的类名都是 "XxxException" 方式
        1. 编译时异常:
                编译时期就会发生的异常, 必须在编译时期处理  Unhandled exception XxxException
        2. 运行时异常:
                编译时正常, 运行时才会发生的异常
异常的产生过程解析
异常产生的过程:
        1. 当执行的代码发生异常操作时, JVM会创建一个对应的异常类对象, 包含异常的内容, 原因, 位置
     2. 如果执行代码的方法没有对异常进行 try...catch 处理, 则会向该方法调用处的方法抛(向上层抛). 如果所有方法(包括main()方法)都没有 try...catch 处理异常, 则该异常会被JVM按照默认的处理方式处理
        3. JVM对于异常的默认处理方式是:
                1. 将异常信息(内容, 原因, 位置)打印到控制台
                2. 终止当前的程序
异常关键字: throw制造异常
throw关键字作用:
        在方法中抛出指定的异常对象
格式:
        throw new 异常类名("异常原因字符串");
        // 示例:
    public static void method(int index) {
        if (index < 0) {
            throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围");
        }
    }
注意:
        1. throw 必须写在方法的内部
        2. throw 后面new的异常对象, 必须是 "Exception" 或 "Excetion的子类" 的对象
        3. 一个方法内部 throw 了一个异常对象, 则该方法可以分为2种情况来处理该异常:
       如果 throw 的是"运行时异常"(RuntimeException及其子类)对象, 那么可以不处理
该异常最终会交给JVM处理, 结果就是: 打印异常信息到控制台, 并立刻结束程序
如果 throw 的是"编译时异常"(Exception及其子类), 则必须处理:
                        处理方式1: throws 抛出
                        处理方式2: try...catch 捕获
异常的处理方式1: throws声明抛出异常
异常处理的第一种方式:
        throws, 声明抛出 (方法自己不处理, 交给方法调用者处理, "甩锅给别人")
        作用: 告诉方法的调用者, 调用此方法有可能发生异常, 需要在编写代码时处理
格式:
        修饰符 返回值类型 方法名() throws 异常类名1, 异常类名2, ... {
   }
注意:
        1. throws 必须写在方法声明上
        2. throws 后面的异常类名, 一般是 Exception 或 Exception的子类
                (RuntimeException及其子类也行, 但是没有什么意义)
        3. 方法内部如果抛出了多个异常对象, throws 后也必须声明多个异常
                如果抛出的异常对象有子父类关系, 那么直接声明父类异常即可
        4. 调用了一个带有 throws 声明抛出异常的方法, 就必须处理该异常:
                要么继续声明 throws 抛出
                要么 try...catch 捕获处理异常
finally代码块
格式:try {
       // 可能发生异常的代码
   } catch(异常类型 异常变量名) {
       // 处理异常
   }
       ...
       catch(异常类型 异常变量名) {
       // 处理异常
   } finally {
       // 无论是否发生异常, 是否捕获, 最后都会执行的代码.
       // 通常在这里执行释放资源的操作
   }
注意:
        1. finally 必须和 try...catch 一起使用
        2. finally 一般用于释放资源 (IO流时用到);
异常注意事项3: 子父类继承重写方法时的异常要求
子父类继承关系下, 子类重写父类带有throws的方法:
        1. 如果父类抛出多个异常, 子类重写父类方法时可以有3种方式:
                a: 抛出和父类相同的异常
                b: 抛出父类异常的子类
                c: 不抛出异常
        2. 父类方法没有抛出异常, 子类重写父类该方法时也不可抛出异常
                此时子类产生该异常, 只能捕获处理, 不能声明抛出
总结:子父类继承关系下,抛出异常,子类需要和父类保持一致,不可用超过父类!!!
自定义异常类
如果Java提供的异常类不足以满足我们的需求, 我们也可以自己定义异常类
        1.定义编译时异常: 继承 Exception
       2. 定义运行时异常: 继承 RuntimeException
多线程计算机基本概念: 并发与并行
并发: (交替执行) 指两个或多个事件在"同一时间段内"发生
并行: (同时执行) 指两个或多个事件在"同一时刻"发生 (同时发生)
计算机基本概念: 进程
进程: 一个应用程序在内存中的一次执行过程
每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程
进程也是程序的一次执行过程,是系统运行程序的基本单位
系统运行一个程序即是一个进程从创建、运行到消亡的过程
计算机基本概念: 线程
线程: 是进程内的一个独立执行单元 (一条代码执行路径)
        一个程序运行后至少有一个进程, 一个进程中可以包含多个线程
多线程的好处: 效率高  多个线程之间互不影响
线程的调度
线程的调度方式:
        1. 分时调度: 所有线程轮流使用CPU, 平分占用CPU的时间
        2. 抢占式调度: 优先让优先级高的线程使用CPU; 如果优先级相同, 则随机选择一个线程执行主线程:
     我们以前编写的代码, 也在一条线程中执行, 该线程叫作"main线程", 也称为"主线程"
   如果我们没有额外创建线程, 那么我们的程序就只有一个线程, 即主线程, 此时程序是"单线程"的

单线程的执行特点:
    同一个线程内的代码, 从上往下依次执行
实现多线程的第一种方式:
  1. 定义类, 继承 Thread 类
   2. 重写 run() 方法, run方法内部是线程要执行的任务
   3. 创建Thread子类的对象, 调用 start() 方法启动线程
java.lang.Thread类: 表示线程. 实现了Runnable接口
void start(): 启动线程, 即让线程开始执行run()方法中的代码

注意:
  必须调用 start() 方法来开启线程, 不能直接调用 run() 方法, 调用 run() 会变成单线程
  同一个线程对象, 不能多次调用 start() 方法
  Java是抢占式调度, 不同线程的代码, 执行顺序是随机的

            

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马