Java 进阶学习笔记day_07(异常、多线程)

异常


  • 指的是java程序运行期间出现的不正常情况,导致jvm终止程序的运行

java是面向对象的语言,产生的每个异常其实都是一个异常对象,每个异常对象一定会有所属的异常类

  • 常见的异常类有:
    - ClassCastException NullPointerException ArrayIndexOutOfBoundsException ArithmeticException

java中默认将异常抛给jvm处理,而jvm处理的方式就是中断运行,将异常信息输出到控制台

  • Throwable类: 是 Java 语言中所有错误或异常类的父类
    - Error类(错误): 表示错误,不可以通过代码进行纠正使得程序继续运行,只能事先避免
    - Exception类(异常):表示异常,可以通过代码进行纠正使得程序继续运行

  • 异常分类
    - 编译异常: 程序在编译期间出现的异常,如果不处理,程序无法通过编译
    - 运行异常: 程序在运行期间出现的异常,如果不处理,程序可以通过编译,但在运行的时候会出现异常

异常的产生和处理

  • throw关键字的作用
    - 在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象
    - throw用在方法内,来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行

	//产生异常并抛出
	throw new ArrayIndexOutOfBoundsException();

声明处理异常_

  • 使用throws关键字将问题标识出来, 表示当前方法不处理异常,而是提醒给调用者, 让调用者来处理
    - throws可以一次抛一个或多个异常
    - 使用声明处理异常,处理完后,如果程序运行期间没有出现异常,程序可以继续往下执行
    - 使用声明处理异常,处理完后,如果程序运行期间有出现异常,程序不可以继续往下执行

	import java.text.ParseException;
	import java.text.SimpleDateFormat;
	import java.util.Date;
	
	public class Text {
	    public static void main(String[] args) throws ParseException {
	        // 编译异常,声明处理
	        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	        Date date = sdf.parse("2000-0-0");
	        System.out.println(date);
	
	        // 运行异常
	        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
	        Date date2 = sdf2.parse("2000-0-0");
	        System.out.println(date2);
	    }
}

声明处理异常用来处理编译异常

捕获处理异常

  • 捕获处理异常也是一种处理异常的方式,这种处理异常的方式处理完异常后,无论程序是否发生异常,程序都可以继续往下执行

格式:


	try{
    // 可能会发生异常的代码
	}catch(异常类型 变量名){
	// 打印异常的信息,发生异常后需要执行的代码
}
  • 注意:
    - try,catch都不能单独使用
    - try中的代码如果发生了异常,try中发生异常位置之后的代码就不执行了
  • 执行流程:
    - 首先执行try中的代码
    - 如果try中的代码发生了异常,就会执行catch里面的代码,执行完catch里面的代码后,程序继续往下执行
    - 如果try中的代码没有发生异常,就不会执行catch里面的代码,而是继续往下执行
  • 获取异常信息: Throwable类
    - public String getMessage():获取异常的描述信息,原因(提示给用户的时候,就提示错误原因
    - public void printStackTrace():打印异常的跟踪栈信息并输出到控制台

	import java.text.ParseException;
	import java.text.SimpleDateFormat;
	import java.util.Date;
	
	public class Text {
	    public static void main(String[] args) throws ParseException {
	        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
	
	        try{
	            Date date2 = sdf2.parse("2000-0-0");
	        }catch (ParseException e){
	            // 获取异常的描述信息,原因(提示给用户的时候,就提示错误原因
	            e.getMessage();
	            // 打印异常的跟踪栈信息并输出到控制台
	            e.printStackTrace();
	        }
	    }
}

finally

  • 因为异常会引发程序跳转,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码在正常情况下一定会被执行的

	try{
    	//可能会出现异常的代码
	}catch(异常的类型 变量名){
	    //处理异常的代码或者打印异常的信息
	}finally{
	    //无论异常是否发生,都会执行这里的代码 (正常情况,都会执行finally中的代码,一般用来释放资源)
}

异常注意事项_

  • try/catch/finally都不可以单独使用
  • 运行时异常被抛出可以不处理(不捕获也不声明抛出)
  • 在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收 (特殊条件下不会执行)

方法重写时的注意事项_

  • 父类的方法抛出异常,子类覆盖(重写)父类方法时,只能抛出相同的异常或该异常子集
  • 父类的方法未抛出的异常,子类覆盖(重写)父类方法时,只能处理,不能抛出

自定义异常

  • 自定义异常类分类
    - 自定义编译期异常: 自定义类 并继承于java.lang.Exception
    - 自定义运行时期异常:自定义类 并继承于java.lang.RuntimeException

	// 编译异常
	public class MyException1 extends Exception {
	}
	// 运行异常
	public class MyException2 extends RuntimeException {
}

多线程

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

并发:指两个或多个事件在同一个时间段内发生(交替执行)

进程与线程_

进程:进程是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程

  • 进程是应用程序的可执行单元
  • 一个应用程序可以有多个进程
  • 每个进程执行都会有独立的内存空间

线程:是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一条线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序

  • 线程是进程的可执行单元
  • 一个进程可以有多条线程
  • 每个线程执行都会有独立的内存空间

java只有单进程,然后有多线程
一个进程一次只能执行一条线程,所以java中只有多线程并发,没有多线程并行

线程的调度_

  • 分时调度:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间
  • 抢占式调度:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性)

Java线程的调度方式: 抢占式

Thread类

  • java.lang.Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例

构造方法_

  • public Thread(Runnable target):创建一个带有指定任务的线程对象,通过参数Runnable指定任务
  • public Thread(Runnable target,String name):创建一个带有指定任务的线程对象并指定线程名字

常用方法_

  • public String getName():获取当前线程名称
  • public void start():导致此线程开始执行 (Java虚拟机调用此线程的run方法)
  • public void run():此线程要执行的任务在此处定义代码
  • public static void sleep(long millis):使当前正在执行的线程以指定的毫秒数暂停执行
  • public static Thread currentThread():返回对当前正在执行的线程对象的引用

继承方式创建线程_


	class MyThread extends Thread{

    @Override
    // 重写run() 方法
    public void run() {
        System.out.println("通过继承方式来创建线程");
    }
	}
	
	public class Text {
	    public static void main(String[] args){
	
			// 输出 通过继承方式来创建线程
	        new MyThread().start();
	
	    }
}

实现方式创建线程_

  • Runnable是一个任务接口,里面有一个抽象方法run(),可以在run方法中书写线程的任务代码

	class MyThread implements Runnable{

    @Override
    public void run() {
        System.out.println("通过实现类方式来创建线程");
    }
	}
	
	public class Text {
	    public static void main(String[] args){
			
			// 输出 通过实现类方式来创建线程
	        new Thread(new MyThread()).start();
	
	    }
}

匿名内部类方式_


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

       new Thread(new Runnable() {
           @Override
           public void run() {
               System.out.println("通过匿名内部类方式来创建线程");
           }
       }).start();
		// 输出 通过匿名内部类方式来创建线程
    }
}

创建并启动多条线程_


	// 用实现的方式
	class MyThread implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "创建了一条线程");
    }
	}
	
	
	public class Text {
	    public static void main(String[] args) {
	
	        new Thread(new MyThread(),"窗口1").start(); // 输出 窗口1创建了一条线程
	        new Thread(new MyThread(),"窗口2").start(); // 输出 窗口2创建了一条线程
	        new Thread(new MyThread(),"窗口3").start(); // 输出 窗口3创建了一条线程
	        new Thread(new MyThread(),"窗口4").start(); // 输出 窗口4创建了一条线程
	    }
}

实现方式创建线程的优势_

  • 实现Runnable接口比继承Thread类所具有的优势

适合多个相同的程序代码的线程去共享同一个资源(任务)
可以避免java中的单继承的局限性
增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立
线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值