JAVA Basics-Chapter 15 Exceptions and Threads

main content

Exceptions, threads,
teaching goals,
able to distinguish the difference between exceptions and errors in the program,
speak the classification of exceptions,
say the way the virtual machine handles exceptions,
list three common runtime exceptions,
be able to use try...catch keywords to handle exceptions,
use the throws keyword Handle exceptions
Ability to customize exception classes
Ability to handle custom exception classes
Speak the concept of processes Speak the concept
of threads
Ability to understand the difference between concurrency and parallelism
Ability to start new threads

# 第一章 异常

## 1.1 异常概念

### 异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将

### 受影响.在程序中的意思就是:

### 异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。

在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处
理异常的方式是中断处理。

The exception does not refer to a syntax error. The syntax is wrong, the compilation fails, and the bytecode file will not be generated, and it will not run at all.

## 1.2 异常体系

异常机制其实是帮助我们找到程序中的问题,异常的根类是java.lang.Throwable,其下有两个子类:
java.lang.Error与java.lang.Exception,平常所说的异常指java.lang.Exception。


Throwable体系:

Error: Severe error Error, an error that cannot be handled, can only be avoided in advance, like a terminal illness.
Exception: indicates an exception. After the exception occurs, the programmer can correct it by means of code to make the program continue to run, which must be handled. It's like
a cold or appendicitis.

Throwable中的常用方法:

public void printStackTrace(): Print the detailed information of the exception.
Contains the type of the exception, the cause of the exception, and the location of the exception. PrintStackTrace must be used in the development and debugging stages.
public String getMessage(): Get the reason for the exception.
When prompted to the user, the reason for the error is prompted.
public String toString(): Get the type and description of the exception (not used).

出现异常,不要紧张,把异常的简单类名,拷贝到API中去查。

## 1.3 异常分类

我们平常说的异常就是指Exception,因为这类异常一旦出现,我们就要对代码进行更正,修复程序。


异常(Exception)的分类:根据在编译时期还是运行时期去检查异常?

Exception during compilation: checked exception. During compilation, it will be checked. If no exception is handled, the compilation will fail. (Such as abnormal date formatting)
Runtime exception: runtime exception. During runtime, check for exceptions. During compilation, runtime exceptions will not be detected by the compiler (no errors will be reported). (E.g. abnormal mathematics
)

## 1.4 异常的产生过程解析

先运行下面的程序,程序会产生一个数组索引越界异常ArrayIndexOfBoundsException。我们通过图解来解析下
异常产生的过程。

工具类

### 测试类

public class ArrayTools { // Obtain the elements of the given array through the given index. public static int getElement(int[] arr, int index) { int element = arr[index]; return element; } }






### 上述程序执行过程图解:

# 第二章 异常的处理

Java异常处理的五个关键字:try、catch、finally、throw、throws

## 2.1 抛出异常throw

### 在编写程序时,我们必须要考虑程序出现问题的情况。比如,在定义方法时,方法需要接受参数。那么,当调用方

### 法使用接受到的参数时,首先需要先对参数数据进行合法的判断,数据若不合法,就应该告诉调用者,传递合法的

### 数据进来。这时需要使用抛出异常的方式来告诉调用者。

在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。那么,抛出一个异常具体如何操作呢?

  1. Create an exception object. Encapsulate some prompt information (information can be written by yourself).
  2. Need to inform the caller of this exception object. How to tell? How to pass this exception object to the caller?
    It can be done with the keyword throw . throw exception object.
    Throw is used in a method to throw an exception object, pass the exception object to the caller, and end the execution of the current method.
使用格式:

public class ExceptionDemo {
public static void main(String[] args) {
int[] arr = { 34 , 12 , 67 };
intnum = ArrayTools.getElement(arr, 4 )
System.out.println(“num=” + num);
System.out.println(“over”);
}
}


### 例如:

学习完抛出异常的格式后,我们通过下面程序演示下throw的使用。

Note: If a problem occurs, we will throw the problem description class or exception, that is, return the problem to the caller
of the method .
So what should be done to the caller? One is to capture processing, and the other is to continue talking about the problem statement and use throws to
declare processing.

## 2.2 Objects非空判断

还记得我们学习过一个类Objects吗,曾经提到过它由一些静态的实用方法组成,这些方法是null-save(空指针安
全的)或null-tolerant(容忍空指针的),那么在它的源码中,对对象为null的值进行了抛出异常操作。

public static T requireNonNull(T obj): Check that the specified reference object is not null.

查看源码发现这里对为null的进行了抛出异常操作:

throw new exception class name (parameter);

throw new NullPointerException("The arr array to be accessed does not exist");

throw new ArrayIndexOutOfBoundsException("The index does not exist in the array and is out of range");

public class ThrowDemo { public static void main(String[] args) { //Create an array int[] arr = {2, 4, 52, 2 }; // Find the corresponding element according to the index int index = 4; int element = getElement(arr, index);





System.out.println(element);
System.out.println(“over”);
}
/*

  • Find the corresponding element in the array according to the index
    /
    public static int getElement(int[] arr,int index){ //Judging whether the index is out of bounds if(index< 0 || index>arr.length-1 ){ /



    Judging if the condition is met , After the execution of throw throws the exception object, the method can no longer continue.
    At this time, the execution of the current method will end, and the exception will be notified to the caller. At this time, it needs to be resolved by exception.
    */
    throw new ArrayIndexOutOfBoundsException("Dude, the corner mark is out of bounds~~~");
    }
    int element = arr[index];
    return element;
    }
    }

## 2.3 声明异常throws

声明异常:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理(稍后讲
解该方式),那么必须通过throws进行声明,让调用者去处理。

关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).

声明异常格式:

### 声明异常的代码演示:

throws用于进行异常类的声明,若该方法可能有多种异常情况产生,那么在throws后面可以写多个异常类,用逗
号隔开。

public static T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}

Modifier return value type method name (parameter) throws exception class name 1, exception class name 2...{}

public class ThrowsDemo {
public static void main(String[] args) throws FileNotFoundException {
read(“a.txt”);
}

// If a problem occurs when defining a function, it needs to be reported to the caller. You can declare by using the throws keyword on the method
public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) {//If it is not a.txt this file // I assume If it is not a.txt, it is an error that the file does not exist, which is an exception throw throw new FileNotFoundException("File does not exist"); } } }





public class ThrowsDemo2 {
public static void main(String[] args) throws IOException {
read(“a.txt”);
}

public static void read(String path)throws FileNotFoundException, IOException { if (!path.equals("a.txt")) {//If it is not a.txt this file // I assume that if it is not a.txt, I think the file is not Existence is an error, that is, an exception throw throw new FileNotFoundException("File does not exist"); } if (!path.equals("b.txt")) { throw new IOException(); } } }









## 2.4 捕获异常try...catch

### 如果异常出现的话,会立刻终止程序,所以我们得处理异常:

  1. This method does not process, but declares to throw, which is handled by the caller of the method (throws).
  2. Use try-catch block in the method to handle exceptions.
try-catch的方式就是捕获异常。

Catch the exception: Java captures the targeted statement of the exception, and can handle the exception in a specified way.

捕获异常语法如下:

try:该代码块中编写可能产生异常的代码。

catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理。

Note: try and catch cannot be used alone, they must be used together.

演示如下:

### 如何获取异常信息:

Throwable类中定义了一些查看方法:

try{ write code that may cause exceptions } catch (exception type e) { handle exception code // log log / print exception information / continue to throw exceptions }




public class TryCatchDemo { public static void main(String[] args) { try {// When an exception occurs, there must be a way to handle it. Either capture or declare. read("b.txt"); } catch (FileNotFoundException e) {// What needs to be defined in the brackets? //What exception is thrown in try, define the exception type in parentheses System.out.println(e); } System.out.println("over"); } /* *










  • There are exceptions in our current method and compile-time exceptions
    */
    public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) {//If it is not a.txt file / / I assume that if it is not a.txt, it is an error that the file does not exist, that is, an exception throw throw new FileNotFoundException("file does not exist"); } } }






public String getMessage(): Get the description information of the exception and the reason (when prompted to the user, the reason of the error will be prompted.

public String toString(): Get the type and description of the exception (not used).
public void printStackTrace(): Print the abnormal trace stack information and output to the console.

包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。

## 2.4 finally 代码块

finally:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行
不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。

什么时候的代码必须最终执行?

当我们在try语句块中打开了一些物理资源(磁盘文件/网络连接/数据库连接等),我们都得在使用完之后,最终关闭打开
的资源。

finally的语法:

try...catch....finally:自身需要处理异常,最终还得关闭资源。

Note: finally cannot be used alone.

比如在我们之后学习的IO流中,当打开了一个关联文件的资源,最后程序不管结果如何,都需要把这个资源关闭
掉。

finally代码参考如下:

When only the related methods of exiting JVM are called in try or catch, finally will not be executed at this time, otherwise finally will always be executed.

public class TryCatchDemo4 { public static void main(String[] args) { try { read("a.txt"); } catch (FileNotFoundException e) { //The catch is the compile-time exception and the run-time throw new RuntimeException(e); } finally { System.out.println("No matter what the program, it will be executed here."); } System.out.println("over"); } /* *












  • There are exceptions in our current method and compile-time exceptions
    */
    public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) {//If it is not a.txt file / / I assume that if it is not a.txt, it is an error that the file does not exist, that is, an exception throw throw new FileNotFoundException("file does not exist"); } } }






## 2.5 异常注意事项

### 多个异常使用捕获又该如何处理呢?

### 1. 多个异常分别处理。

### 2. 多个异常一次捕获,多次处理。

### 3. 多个异常一次捕获一次处理。

### 一般我们是使用一次捕获多次处理方式,格式如下:

Note: This exception handling, requiring multiple exceptions can not catch in the same, and there are different between when the parent sub-plurality of catch abnormal
relations normal, then the catch subclass exception handling requirements above, the parent class The exception is handled in the catch below.

Runtime exceptions may not be handled if they are thrown. Neither capture nor declare to throw.
If finally has a return statement, always return the result in finally to avoid this situation.

try{ write code that may have exceptions }catch(exception type A e){ When an A type exception occurs in the try, use the catch to catch it. The code for handling the exception //record the log/print the exception information/continue to throw the exception }catch(Exception type B e){ When a type B exception occurs in the try, use the catch to catch it. The code for handling the exception //record the log/print the exception information/continue to throw the exception }








### 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异

### 常。

### 父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不

### 能声明抛出

# 第三章 自定义异常

## 3.1 概述

### 为什么需要自定义异常类:

我们说了Java中不同的异常类,分别表示着某一种具体的异常情况,那么在开发中总是有些异常情况是SUN没有定义
好的,此时我们根据自己业务的异常情况来定义异常类。例如年龄负数问题,考试成绩负数问题等等。

在上述代码中,发现这些异常都是JDK内部定义好的,但是实际开发中也会出现很多异常,这些异常很可能在JDK中
没有定义过,例如年龄负数问题,考试成绩负数问题.那么能不能自己定义异常呢?

什么是自定义异常类:

在开发中根据自己业务的异常情况来定义异常类.

自定义一个业务逻辑异常: RegisterException。一个注册异常类。

异常类如何定义:

  1. Customize a compile-time exception: Customize the class and inherit from java.lang.Exception.
  2. Customize a runtime exception class: custom class and inherit from java.lang.RuntimeException.
## 3.2 自定义异常的练习

### 要求:我们模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已经被注册。

首先定义一个登陆异常类RegisterException:

### 模拟登陆操作,使用数组模拟数据库中存储的数据,并提供当前注册账号是否存在方法用于判断。

### // 业务逻辑异常

public class RegisterException extends Exception {
/**

  • Null parameter construction
    */
    public RegisterException() { }

/**
*

  • @param message means abnormal prompt
    */
    public RegisterException(String message) { super(message); } }



# 第四章 多线程

### 我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏

### 边听歌,怎么设计?

### 要解决上述问题,咱们得使用多进程或者多线程来解决.

## 4.1 并发与并行

### 并发:指两个或多个事件在同一个时间段内发生。

### 并行:指两个或多个事件在同一时刻发生(同时发生)。

public class Demo { // An account already exists in the simulation database private static String[] names = {"bill","hill","jill"};

public static void main(String[] args) { //Call method try{ // Code that may be abnormal checkUsername("nill"); System.out.println("Registration successful");//If there is no exception, register Success }catch(RegisterException e){ //Handle the exception e.printStackTrace(); } }









//Determine whether the current registered account exists
//Because it is a compile-time exception and want the caller to handle it, declare the exception
public static boolean checkUsername(String uname) throws LoginException{ for (String name: names) { if(name.equals (uname)){//If the name is in it, throw a login exception throw new RegisterException("Dear"+name+"has been registered!"); } } return true; } }








### 在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多个程序同时运行,这在单 CPU 系统中,每

### 一时刻只能有一道程序执行,即微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那是因为分

### 时交替运行的时间是非常短的。

### 而在多个 CPU 系统中,则这些可以并发执行的程序便可以分配到多个处理器上(CPU),实现多任务并行执行,

### 即利用每个处理器来处理一个可以并发执行的程序,这样多个程序便可以同时执行。目前电脑市场上说的多核

### CPU,便是多核处理器,核 越多,并行处理的程序越多,能大大的提高电脑运行的效率。

### 注意:单核处理器的计算机肯定是不能并行的处理多个任务的,只能是多个任务在单个CPU上并发运行。同

### 理,线程也是一样的,从宏观角度上理解线程是并行运行的,但是从微观角度上分析却是串行运行的,即一个

### 线程一个线程的去运行,当系统只有一个CPU时,线程会以某种顺序执行多个线程,我们把这种情况称之为

### 线程调度。

## 4.2 线程与进程

### 进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多

### 个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创

### 建、运行到消亡的过程。

### 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程

### 中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

### 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程

### 我们可以再电脑底部任务栏,右键----->打开任务管理器,可以查看当前任务的进程:

### 进程


### 线程


### 线程调度:

### 分时调度

### 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。

### 抢占式调度

Give priority to threads with higher priority to use the CPU. If the threads have the same priority, one will be randomly selected (thread randomness). Java uses
preemptive scheduling.
Set thread priority


### 抢占式调度详解

### 大部分操作系统都支持多进程并发运行,现在的操作系统几乎都支持同时运行多个程序。比如:现在我

们上课一边使用编辑器,一边使用录屏软件,同时还开着画图板,dos窗口等软件。此时,这些程序是
在同时运行,”感觉这些软件好像在同一时刻运行着“。

实际上,CPU(中央处理器)使用抢占式调度模式在多个线程间进行着高速的切换。对于CPU的一个核而
言,某个时刻,只能执行一个线程,而 CPU的在多个线程间切换速度相对我们的感觉要快,看上去就是
在同一时刻运行。 其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的
使用率更高。


## 4.3 创建线程类

Java使用java.lang.Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用是
完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。
Java中通过继承Thread类来创建并启动多线程的步骤如下:

  1. Define a subclass of the Thread class and rewrite the run() method of this class. The method body of the run() method represents the task that the thread needs to complete, so the
    run() method is called the thread execution body.
  2. Create an instance of the Thread subclass, that is, create a thread object
  3. Call the start() method of the thread object to start the thread
代码如下:

测试类:

### 自定义线程类:

public class Demo01 { public static void main(String[] args) { //Create a custom thread object MyThread mt = new MyThread("New thread!"); //Start a new thread mt.start(); //In Execute the for loop in the main method for (int i = 0; i <10; i++) { System.out.println("main thread!"+i); } } }










public class MyThread extends Thread { //Define the construction method of the specified thread name public MyThread(String name) { //Call the construction method of the String parameter of the parent class and specify the name of the thread super(name); } /**






### /**

 * 重写run方法,完成该线程执行的逻辑
 */
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName()+":正在执行!"+i);
}
}
}

Guess you like

Origin blog.csdn.net/weixin_43419256/article/details/108230713