我的java学习第六天

2021/8/23 9:28:28

本文主要是介绍我的java学习第六天,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Day6

1.异常

异常定义

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

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

异常分类

编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)

运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)

异常处理

  1. 创建一个异常对象。封装一些提示信息(信息可以自己编写)。

  2. 需要将这个异常对象告知给调用者。怎么告知呢?怎么将这个异常对象传递到调用者处呢?通过关键字throw 就可以完成。throw 异常对象。

throw new 异常类名(参数);

异常声明

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

修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }

捕获异常

Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式的处理。

try{ 
    编写可能会出现异常的代码 
}catch(异常类型 e){ 
    处理异常的代码 
    //记录日志/打印异常信息/继续抛出异常 
}

自定义异常

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

  1. 自定义一个编译期异常: 自定义类 并继承于

    java.lang.Exception 。

  2. 自定义一个运行时期的异常类:自定义类 并继承于java.lang.RuntimeException 。

多个异常

try{ 
    编写可能会出现异常的代码 
}catch(异常类型A e){ 
    当try中出现A类型异常,就用该catch来捕获. 处理异常的代码 
    //记录日志/打印异常信息/继续抛出异常 
}catch(异常类型B e){ 
    当try中出现B类型异常,就用该catch来捕获. 处理异常的代码 
    //记录日志/打印异常信息/继续抛出异常 
}

注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异 常的关系,那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。

Finally 代码块

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

finally不能单独使用

try { 
    read("a.txt"); 
} catch (FileNotFoundException e) { 
    //抓取到的是编译期异常 抛出去的是运行期 
    throw new RuntimeException(e); 
} finally { 
    System.out.println("不管程序怎样,这里都将会被执行。"); 
}

2.线程

并发与并行

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

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

线程与进程

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

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

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

创建线程

1.使用继承的方式
public class MyThread extends Thread{
    /*
    * 利用继承中的特点
    * 将线程名称传递 进行设置
    */
    public MyThread(String name){
        super(name);
    }
    /*
    * 重写run方法
    * 定义线程要执行的代码
    */
    public void run(){
        for (int i = 0; i < 20; i++) {
        //getName()方法 来自父亲
        System.out.println(getName()+i);
        }
    }
}
2.使用定义接口的实现类重写
  1. 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

  2. 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正 的线程对象。

  3. 调用线程对象的start()方法来启动线程。

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
        System.out.println(Thread.currentThread().getName()+" "+i);
        }
    }
}
3.二者区别

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

  1. 适合多个相同的程序代码的线程去共享同一个资源。

  2. 可以避免java中的单继承的局限性。

  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。

  4. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

    扩充:在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用 java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进 程。

线程安全

如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样 的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写 操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步, 否则的话就可能影响线程安全。

线程同步

同步锁: 对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁.

  1. 锁对象 可以是任意类型。

  2. 多个线程对象 要使用同一把锁。 注意:在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着 (BLOCKED)。

1.同步代码块

同步代码块: synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。

格式:

synchronized(同步锁){
    需要同步操作的代码
}

使用同步代码块解决代码:

public class Ticket implements Runnable{
    private int ticket = 100;
    Object lock = new Object();
    /*
    * 执行卖票操作
    */
    @Override
    public void run() {
    //每个窗口卖票的操作
    //窗口 永远开启
        while(true){
            synchronized (lock) {
                if(ticket>0){
                    //有票 可以卖
                    //出票操作
                    //使用sleep模拟一下出票时间
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        // TODO Auto‐generated catch block
                        e.printStackTrace();
                    }
                    //获取当前线程对象的名字
                    String name = Thread.currentThread().getName();
                    System.out.println(name+"正在卖:"+ticket‐‐);
                }
            }
        }
    }
}
2.同步方法
public class Ticket implements Runnable{
    private int ticket = 100;
    /*
    * 执行卖票操作
    */
    @Override
    public void run() {
    //每个窗口卖票的操作
    //窗口 永远开启
        while(true){
            sellTicket();
        }
    }
    
    public synchronized void sellTicket(){
        if(ticket>0){
            //有票 可以卖
            //出票操作
            //使用sleep模拟一下出票时间
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto‐generated catch block
                e.printStackTrace();
            }
                //获取当前线程对象的名字
                String name = Thread.currentThread().getName();
                System.out.println(name+"正在卖:"+ticket‐‐);
        }
    }
}
3.Lock锁
ublic class Ticket implements Runnable{
    private int ticket = 100;
    Lock lock = new ReentrantLock();
    /*
    * 执行卖票操作
    */
    @Override
    public void run() {
        //每个窗口卖票的操作
        //窗口 永远开启
        while(true){
            lock.lock();
            if(ticket>0){//有票 可以卖
                //出票操作
                //使用sleep模拟一下出票时间
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    // TODO Auto‐generated catch block
                    e.printStackTrace();
                }
            //获取当前线程对象的名字
            String name = Thread.currentThread().getName();
            System.out.println(name+"正在卖:"+ticket‐‐);
            }
            lock.unlock();
        }
    }
}

线程状态

线程状态导致状态发生条件
NEW(新建) 线程刚被创建,但是并未启动。还没调用start方法。
Runnable(可运行) 线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器。
Blocked(锁阻塞) 当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。
Waiting(无限等待) 当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。
Timed Waiting(计时等待) 同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。这一状态将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep 、Object.wait。
Teminated(被终止) 因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。





这篇关于我的java学习第六天的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程