java基础之异常与多线程

java之异常???

异常本身就是一个类,处理方式是中断。

异常体系:

Throwable体系:异常的根类是java.lang.Throwable类
Error:严重错误Error,无法通过处理的错误,只能事先避免,好比绝症。必须修改源代码了,程序才能继续执行。
Exception:表示异常(编译期异常),程序得了一个小毛病,处理掉,程序可以继续执行。其下还有一个子类RuntimeException:运行期异常。无须处理。

异常的处理:

throw:关键字,在指定的方法中抛出指定的异常

格式:

throw new xxxException(“异常产生的原因”);//新建的一个对象

注意:

   1、throw关键字必须写在方法的内部

  2、throw关键字后面的new对象必须是Exception或者Exception子类对象

  3、抛出后,就必须处理

            new后面若是RuntimeException或者RuntimeException子类对象,可以不处理,默认交给JVM处理(打印异常对象,中断程序)

          new后面是编译异常(写代码的时候报错),我们就必须处理,要么throws要么try...catch

 

objects非空判断:里面有个静态方法

public static <T> T requireNonNull(T obj)查看指定引用对象不是null

 

声明异常throws:

异常处理的第一种方式,交给别人处理

作用:会把异常对象声明抛出方法的调用者处理(自己不处理,给别人处理),最终交给JVM处理---->中断处理。

使用格式:在方法声明时使用

        修饰符  返回值类型   方法名(参数列表)throws xxxException,...{

             throw new  xxxExcepton("产生的原因");

            ...(其他异常)与throws后面是一样的,声明什么异常就抛出什么异常

}

注意事项:

1、必须写在方法声明中

2、throws抛出的对象必须是Exception或者Exception子类对象

3、方法内部如果出现了多个异常对象,那么throws后边也必须声明多个异常

          如果抛出的多个异常对象有子父类关系,那么直接处理父类异常即可

4、调用了一个声明抛出的异常的方法,就必须处理声明的异常

             要么继续使用throws声明抛出,交给方法的调用者处理,最终交给jvm

              要么try...catch自己处理异常

 

捕获异常:try..catch:

异常处理的第二种方式,自己处理异常

格式:

        try{

           可能产生的异常代码

}catch(定义一个异常的变量,用来接收try中抛出的异常对象){

      异常处理逻辑,产生异常对象之后,怎么处理异常对象,一般在工作中,会将异常的信息记录到一个日志中

}

.....

catch(异常类名,变量名){

}

 注意:

1、try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象

2、如果try中产生了异常,就会执行catch中的异常处理逻辑。执行完毕后,继续执行try...catch后的代码

     如果try中没有产生异常就不会执行catch中的代码,而是执行try中的代码及后续代码

如何获取异常信息呢?Throwable类三个静态方法

public String getMessage() :返回throwable简短描述
public String toString() :返回throwable详细消息字符串,重写object类的toString方法
public void printStackTrace() :jvm打印异常对象,默认的方法,打印的异常最全面

 

finally代码块:

格式:跟try一起使用的

try{

}catch(){

}finally{

  //无论是否出现异常都会执行

}

注意:

1、一般用于资源回收

 

多个异常使用捕获又该如何处理呢?
1. 多个异常分别处理。
2. 多个异常一次捕获,多次处理。
3. 多个异常一次捕获一次处理。

 

异常注意事项:

1、如果finally有return语句,永远返回finally中的结果,一般情况下要避免该情况.,返回一个数也没有意义,final一般是作为释放资源用的。

2、父类异常什么样,子类异常就是什么样。


自定义异常:

格式:

public class xxxExcepition extends Exception  |  RuntimeException{

        添加一个空参数的构造方法

       添加一个带异常信息的构造方法

带异常信息的构造方法,方法内部会调用父类带异常信息的构造方法,让父类来处理这个异常信息。

 

多线程:

并发与并行概念?

并发:指交替执行。
并行:同时执行。脑补两个CPU的场景。其实现在大多都是多核CPU

 

线程与进程概念?

进程:进入到内存中的程序叫进程

线程:应用程序到cpu的执行路径,是进程中的一个执行单元,负责程序执行

 

线程调度?

1、分时调度:轮流使用cpu

2、抢占式调度:优先级高先执行,相同,会随机选择一个执行。java也是抢占式调试。

 

主线程概念?

执行主方法的线程。主方法也是就main。

创建多线程java程序?

第一种方式:创建thread子类。java.lang.thread,描述线程类,要实现多线程就要继承它

步骤:

1、创建一个Thread子类

2、重写其子类的run方法,设置络任务(开启线程要做什么)

3、创建Thread类的子类对象

4、调用Thread类中的start方法,开启新的线程执行run方法。

 

第二种方式:实现Runnable接口,场景是打算通过某一线程执行其实现类

步骤:

    1、创建一个Runable接口实现类

     2、在实现类中重写Runable接口的run方法,设置线程任务

      3、创建一个Runable接口的实现类对象

      4、创建Thread类对象,构造方法中传递Runable接口的实现类对象

       5、调用Thread类中的start方法,开启新的线程执行run方法

 

实现Runable接口创建多线程的好处?

1、避免单继承的局限性,实现Runable接口,还可以继承其他的类,实现其他接口

2、增强了程序扩展性,降低了程序的耦合性(解耦),把设置线程与开启线程进行了分离(解耦),实现类中,重写了run方法,用来设置线程任务,创建Thread类对象,调用start方法,用来开启新线程。

 

匿名内部类方式实现线程的创建?

作用:简化代码

           把子类继承父类,重写父类的方法,创建子类对象合一步完成

           把实现类/实现类接口,重写接口中的方法,创建实现类对象合一步完成

格式:

         new 父类/接口(){

              重复父类/接口中的方法

}
 

Thread类的静态方法?

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

线程同步机制:访问共享数据就会出现线程安全问题。

解决:

1、同步代码块

格式:

   synchronized(锁对象){

      可能会出现线程安全问题的代码;

}

注意:

1、通过代码块中的锁对象(相等于嵌入式同步里信号量为1的情况),可以使用任意的对象如object类对象。

2、但必须保证多个线程使用的锁对象是同一个

3、锁对象作用:把同步代码锁住,只让一个线程在同步代码块中执行。

 

2. 同步方法。

使用步骤:

1、把访问了共享数据的代码抽取出来,放到一个方法中

2、在方法上添加syncranized修饰符

格式:就是定义方法

修饰符(如public)  synchranized 返回值类型 方法名(参数列表){

           可能会出现线程安全问的代码

}

原理:同步的锁对象,就是实现类对象new RunnableImpl(),也就是this


3. 锁机制。

java.util.concurrent.locks.Lock接口。

lock接口的方法:

public void lock() :获取锁
public void unlock() :释放锁。

使用步骤:java.util.concurrent.locks.Reentrontlock 实现了lock接口

1、在成员位置创建一个Reentrantlock对象

2、在可能出现安全问题的代码前调用lock获取锁

3、在可能出现安全问题的代码后调用unlock 释放锁。

 

等待唤醒机制:

线程的状态:如下图:

Timed Waiting:计时等待,执行sleep(带参)方法

BLOCKED(锁阻塞):接同步时的等待锁。

Waiting(无限等待):线程之间的通讯,与嵌入式的通讯的内容是一样的。

过程:创建一个消者费线程

调用wait方法,放弃cpu的执行,进入到Watting方法(无限等待)

创建一个生产者线程

调用notify方法,唤醒消费者线程

注意:

生产与消费者线程必须使用同步代码包裹起来,保证等待和唤醒只能有一个在执行

同步使用的锁对象必须保证唯一。

只有锁对象才能调用wait和notify方法

Object类中的方法

void wait():在其他线程调用此对象的notify()方法或notifyAll()方法前,导致当前线程等待

void notify():唤醒在此对象监视器上等待的单个线程,会继续执行wait方法之后的代码。

进入到TimeWaiting(计时等待)有两种方式

1、使用sleep(long m)方法,在毫秒值结束之后,线程睡醒进入到Runnable/Blocked状态

2、使用wait(long m)方法,wait方法如果在毫秒值结束之后,还没有被notify唤醒,就会自动醒来,线程睡醒后进入到Runnable/Blocked状态。

唤醒方法:

void notify()唤醒在此对象监视器上等待的单个线程

void notifyAll()唤醒在此对象监视器上等待的所有线程。

 

线程池:底层原理:一个容器

当程序第一次启动的时候创建多个线程保存到一个集合中,其中的线程可以反复使用。用线程池来管理线程。

实现:jdk1.5后 java自带线程池

java.util.concurrent.Executors:线程池工厂类,用来生成线程池

Executors类中的静态方法:

               static  ExecutorService newFixedThreadPool(int nThreads)创建一个可重用固定线程数的线程池

               参数:

                        int nThreads:创建线程池中包含的线程数量 

               返回值:

                         ExcutorService接口,返回的是ExecuorService接口的实现类对象

java.util.concurrent.ExecutorService:线程池接口

                       用来从线程池中获取线程,调用start方法执行线程任务

                           submit(Runnable task)提交一个 Runnable  任务用于执行

                      关闭/销毁线程的方法:

                                 void shutdown();

线程池的使用步骤:

1、使用线程池的工厂类ExecutorService newFixedThreadPool生产一个指定线程数量的线程池

2、创建一个类,实现Runnable接口 ,重写run方法,设置线程任务

3、调用ExecutorService中的方法submit传递线程任务(实现类),开启线程,执行run方法

4、调用shutdown销毁线程池(不建议执行)

 

函数式编程思想:

有输入量、输出量的一套计算方案,也就是"拿什么东西做什么事情“。

面向对象思想:做一件事情,得找一个能解决这个事情的对象,调用对象方法完成事情。

函数式编程思想:只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程。

Lambda表达式的标准格式:

1、一些参数

2、一个箭头

3、一段代码

(参数列表)   --->   {一些重写方法的代码}

     ():接口中抽象方法的参数列表,没有参数就空着,多个参数使用逗号分隔;参数的数据类型可以省略,如果参数只有一个,类型和小括号()都可省略

     --->:传递的意思,把参数传递给方法体{}

     {}:重写接口的抽象方法的方法体。如果只有一行代码,{}和;return(有返回) 都可省略。

省略规则就是可推导可省略。

Lambda的使用前提:

1. 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。
 

2. 使用Lambda必须具有上下文推断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guangod

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值