第五知识单元

高级编程

Java程序设计 第9讲,主讲人:李欣

Created: 2022-10-17 Mon 03:45

0.1. 互动课堂

Click to host the seminar.

0.2. 签到

https://xin.blue/tool/attendance/

0.3. 本次课的目标

  • 异常处理
    • 了解 异常的 概念意义
    • 了解 预定义异常自定义异常
    • 理解 异常处理 过程
    • 了解 异常 转移
  • 多线程
    • 了解 进程线程关系
    • 理解 两种实现多线程的 方式ThreadRunnable
    • 了解线程的 同步互斥

1. 异常处理

1.1. 错误

1.1.1. 语法错误

public class ShowSyntaxError{
    public static void main(String[] args) {
        // int i = 30;
        i = 30;
        System.out.print(i + 4);
    }
}
ShowSyntaxError.java:4: error: cannot find symbol
        i = 30;
        ^
  symbol:   variable i
  location: class ShowSyntaxError
ShowSyntaxError.java:5: error: cannot find symbol
        System.out.print(i + 4);
                         ^
  symbol:   variable i
  location: class ShowSyntaxError
2 errors

1.1.2. 运行错误

public class ShowRuntimeError {
    public static void main(String[] args) {
        int i = 1 / 0;
    }
}
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at ShowRuntimeError.main(ShowRuntimeError.java:3)

1.1.3. 逻辑错误

public class ShowLogicError {
    public static void main(String[] args) {
        int n1 = 3;
        int n2 = 2;
        n2 += n1 + n2;
        System.out.println("n2 is " + n2);
    }
}
n2 is 7

1.2. 异常

1.2.1. 系统定义的运行异常

系统定义的运行异常 异常对应的系统运行错误
ClassNotFoundException 未找到要加载的类
ArrayIndexOutOfBoundsException 数组越界
FileNotFoundException 未找到指定的文件或目录
IOException 输入、输出错误
NullPointerException 引用空的尚无内存空间的对象变量
ArithmeticException 算术错误,如除数为0
InterruptedException 线程在睡眠、等待或因其他原因暂停时被其他线程打断
UnknownHostException 无法确定主机的IP地址
SecurityException 安全性错误,如Applet欲读写文件
MalformedURLException URL格式错误

1.2.2. 用户自定义的异常

public class Main {
    public static void main(String[] args) {
        String ageString = "23";
        try {
            if (Integer.parseInt(ageString) < 0)
                throw new NegativeAgeException("Please enter a positive age");
            else
                System.out.println(ageString);
        }
        catch(NegativeAgeException e){
            System.out.println(e);
        }
    }
}
class NegativeAgeException extends Exception { // 或者:extends Throwable
    public NegativeAgeException() {}
    public NegativeAgeException(String message) {
        super(message);
    }
}
23
public class Main {
    public static void main(String[] args) {
        String ageString = "23.5";
        try {
            if (Integer.parseInt(ageString) < 0)
                throw new NegativeAgeException("Please enter a positive age");
            else
                System.out.println(ageString);
        }
        catch(NegativeAgeException e){
            System.out.println(e);
        }
    }
}
class NegativeAgeException extends Exception { // 或者:extends Throwable
    public NegativeAgeException() {}
    public NegativeAgeException(String message) {
        super(message);
    }
}
Exception in thread "main" java.lang.NumberFormatException: For input string: "23.5"
        at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.base/java.lang.Integer.parseInt(Integer.java:652)
        at java.base/java.lang.Integer.parseInt(Integer.java:770)
        at Main.main(Main.java:5)
public class Main {
    public static void main(String[] args) {
        String ageString = "-23";
        try {
            if (Integer.parseInt(ageString) < 0)
                throw new NegativeAgeException("Please enter a positive age");
            else
                System.out.println(ageString);
        }
        catch(NegativeAgeException e){
            System.out.println(e);
        }
    }
}
class NegativeAgeException extends Exception { // 或者:extends Throwable
    public NegativeAgeException() {}
    public NegativeAgeException(String message) {
        super(message);
    }
}
NegativeAgeException: Please enter a positive age
public class Main {
    public static void main(String[] args) {
        String ageString = "-23";
        try {
            if (Integer.parseInt(ageString) < 0)
                throw new NegativeAgeException("Please enter a positive age");
            else
                System.out.println(ageString);
        }
        catch(NegativeAgeException e){
            e.printStackTrace();
        }
    }
}
class NegativeAgeException extends Exception { // 或者:extends Throwable
    public NegativeAgeException() {}
    public NegativeAgeException(String message) {
        super(message);
    }
}
NegativeAgeException: Please enter a positive age
        at Main.main(Main.java:6)
public class Main {
    public static void main(String[] args) {
        String ageString;
        int age;
        try {
            ageString = "23.3";
            age = Integer.parseInt(ageString);
            ageString = "-23";
            age = Integer.parseInt(ageString);
            if (age < 0)
                throw new NegativeAgeException("Please enter a positive age");
            else
                System.out.println(ageString);
        }
        catch(NegativeAgeException e) {
            System.out.println(e);
        }
        catch(NumberFormatException e) {
            System.out.println(e);
        }
    }
}
class NegativeAgeException extends Exception { // 或者:extends Throwable
    public NegativeAgeException() {}
    public NegativeAgeException(String message) {
        super(message);
    }
}
java.lang.NumberFormatException: For input string: "23.3"
public class Main {
    public static void main(String[] args) {
        String ageString;
        int age;
        try {
            // ageString = "23.3";
            // age = Integer.parseInt(ageString);
            ageString = "-23";
            age = Integer.parseInt(ageString);
            if (age < 0)
                throw new NegativeAgeException("Please enter a positive age");
            else
                System.out.println(ageString);
        }
        catch(NegativeAgeException e) {
            System.out.println(e);
        }
        catch(NumberFormatException e) {
            System.out.println(e);
        }
    }
}
class NegativeAgeException extends Exception { // 或者:extends Throwable
    public NegativeAgeException() {}
    public NegativeAgeException(String message) {
        super(message);
    }
}
NegativeAgeException: Please enter a positive age
public class Main {
    public static void main(String[] args) {
        String ageString;
        int age;
        // ageString = "23.3";
        // age = Integer.parseInt(ageString);
        ageString = "-23";
        age = Integer.parseInt(ageString);
        if (age < 0)
            throw new NegativeAgeException("Please enter a positive age");
        else
            System.out.println(ageString);
    }
}
class NegativeAgeException extends Exception { // 或者:extends Throwable
    public NegativeAgeException() {}
    public NegativeAgeException(String message) {
        super(message);
    }
}
Main.java:10: error: unreported exception NegativeAgeException; must be caught or declared to be thrown
            throw new NegativeAgeException("Please enter a positive age");
            ^
1 error
public class Main {
    public static void main(String[] args) throws NegativeAgeException {
        String ageString;
        int age;
        // ageString = "23.3";
        // age = Integer.parseInt(ageString);
        ageString = "-23";
        age = Integer.parseInt(ageString);
        if (age < 0)
            throw new NegativeAgeException("Please enter a positive age");
        else
            System.out.println(ageString);
    }
}
class NegativeAgeException extends Exception { // 或者:extends Throwable
    public NegativeAgeException() {}
    public NegativeAgeException(String message) {
        super(message);
    }
}
Exception in thread "main" NegativeAgeException: Please enter a positive age
        at Main.main(Main.java:10)

2. 多线程

2.1. 创建 Thread 类的子类

public class Main {
    public static void main(String[] args) {
        ThreadDemo thread = new ThreadDemo();
        thread.start();
        for(int i = 0; i < 10; i++) {
            System.out.println("Main Thread: " + i);
            try { Thread.sleep(5); } catch (InterruptedException e) { return; }
        }
    }
}
class ThreadDemo extends Thread {
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("New Thread: " + i);
            try { sleep(5); } catch (InterruptedException e) { return; }
        }
    }
}
New Thread: 0
Main Thread: 0
Main Thread: 1
New Thread: 1
Main Thread: 2
New Thread: 2
Main Thread: 3
New Thread: 3
Main Thread: 4
New Thread: 4
Main Thread: 5
New Thread: 5
Main Thread: 6
New Thread: 6
Main Thread: 7
New Thread: 7
Main Thread: 8
New Thread: 8
Main Thread: 9
New Thread: 9
public class Main {
    public static void main(String[] args) {
        ThreadDemo thread = new ThreadDemo();
        thread.start();
        for(int i = 0; i < 10; i++) {
            System.out.println("Main Thread: " + i);
        }
    }
}
class ThreadDemo extends Thread {
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("New Thread: " + i);
        }
    }
}
Main Thread: 0
Main Thread: 1
New Thread: 0
New Thread: 1
New Thread: 2
Main Thread: 2
New Thread: 3
New Thread: 4
Main Thread: 3
Main Thread: 4
New Thread: 5
Main Thread: 5
Main Thread: 6
Main Thread: 7
Main Thread: 8
Main Thread: 9
New Thread: 6
New Thread: 7
New Thread: 8
New Thread: 9

2.2. 实现 Runnable 接口

public class Main {
    public static void main(String[] args) {
        Runnable runnable = new RunnableDemo(); // 创建Runnable接口对象
        Thread thread = new Thread(runnable); // 利用Runnable接口的对象创建Thread类对象
        thread.start(); // 调用Thread类的start方法来启动新线程
        for(int i = 0; i < 10; i++){
            System.out.println("Main Thread: " + i);
        }
    }
}
class RunnableDemo implements Runnable {
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("New Thread: " + i);
        }
    }
}
Main Thread: 0
Main Thread: 1
New Thread: 0
New Thread: 1
Main Thread: 2
Main Thread: 3
Main Thread: 4
Main Thread: 5
Main Thread: 6
Main Thread: 7
New Thread: 2
Main Thread: 8
Main Thread: 9
New Thread: 3
New Thread: 4
New Thread: 5
New Thread: 6
New Thread: 7
New Thread: 8
New Thread: 9
public class Main {
    public static void main(String[] args) {
        RunnableDemo runnable = new RunnableDemo();
        runnable.start();
    }
}
class RunnableDemo implements Runnable {
    public void start() {
        Thread thread1 = new Thread(this, "First Thread");
        Thread thread2 = new Thread(this, "Second Thread");
        thread1.start();
        thread2.start();
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
}
Second Thread: 0
Second Thread: 1
Second Thread: 2
Second Thread: 3
Second Thread: 4
Second Thread: 5
First Thread: 0
Second Thread: 6
Second Thread: 7
Second Thread: 8
Second Thread: 9
First Thread: 1
First Thread: 2
First Thread: 3
First Thread: 4
First Thread: 5
First Thread: 6
First Thread: 7
First Thread: 8
First Thread: 9
public class Main {
    public static void main(String[] args) {
        RunnableDemo runnable = new RunnableDemo();
        runnable.start();
    }
}
class RunnableDemo implements Runnable {
    private int i = 0;
    public void start() {
        Thread thread1 = new Thread(this, "First Thread");
        Thread thread2 = new Thread(this, "Second Thread");
        thread1.start();
        thread2.start();
    }
    public void run() {
        for (; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
}
Second Thread: 0
Second Thread: 1
Second Thread: 2
Second Thread: 3
Second Thread: 4
First Thread: 0
First Thread: 6
Second Thread: 5
Second Thread: 8
Second Thread: 9
First Thread: 7
public class Main {
    public static void main(String[] args) {
        RunnableDemo runnable = new RunnableDemo();
        runnable.start();
    }
}
class RunnableDemo implements Runnable {
    private int i = 0;
    public void start() {
        Thread thread1 = new Thread(this);
        Thread thread2 = new Thread(this);
        Thread thread3 = new Thread(this);
        Thread thread4 = new Thread(this);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }
    public void run() {
        while (i < 10) {
            synchronized(this) {
                System.out.println(Thread.currentThread().getName() + ": " + i);
                i++;
            }
            try { Thread.sleep(1000); } catch (InterruptedException e) { return; }
        }
    }
}
Thread-0: 0
Thread-3: 1
Thread-2: 2
Thread-1: 3
Thread-0: 4
Thread-1: 5
Thread-2: 6
Thread-3: 7
Thread-0: 8
Thread-1: 9