异常
指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行。
异常处理
五个关键字:try/catch/finally/throw/throws
throws:异常处理的第一种方式,交给别人处理。最终会交给JVM处理,中断处理。
try-catch:异常处理的第二种方式,自己处理。可用多个catch处理多个异常对象。若catch里面定义的异常变量,如果有子父类关系,那么子类的异常变量必须写在上边,否则报错。
finally必须和try一起使用,一般用于资源回收
子父类异常注意:父类异常是什么样,子类异常就是什么样。尤其子类重写父类方法时注意。
进程与线程
并发:指两个或多个事件在同一时间段内发生。并行:指两个或多个事件在同一时刻发生(同时发生)。
进程:指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,时系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
线程调度
分为:分时调度和抢占式调度
创建多线程程序
第一种方式:创建Thread类的子类,在子类中重写Thread类中的run方法,设置线程任务,创建Thread子类对象,启动start方法。。
JAVA程序属于抢占式调度,哪个线程的优先级高,哪个先执行,同一个优先级,随机执行。
第二种方式:实现Runnable接口,创建一个Runnable接口的实现类,在实现类中重写runnalbe接口的run方法,设置线程任务,创建接口实现类对象,创建Thread对象,构造方法中传递Runnable接口的实现类对象,调用Thread类中的start方法。
在创建多线程程序中,尽量使用Runnable接口创建。好处:1、避免了单继承的局限性。2、增强了程序的扩展性,降低了程序的耦合性。
可用匿名内部类实现线程的创建。
线程安全
有三种方式完成同步操作,实现线程安全:同步代码块,同步方法,锁机制
同步代码块:synchronized(锁对象){可能会出现线程安全问题的代码(访问了共享数据的代码)}
使用同步方法:把访问了共享数据的代码抽取出来,放到一个方法中,在方法上添加synchronized修饰符
使用Lock锁:在成员位置上创建一个ReentrantLock对象,在可能会出现安全问题的代码前调用Lock接口总的方法Lock获取锁,在可能出现安全问题的代码后调用Lock接口中的方法Unlock释放锁。
线程状态如下图
线程间通信:多个线程在处理同一资源,但处理的动作(线程的任务)却不相同。
为什么要处理线程间的通信:
多个线程并发执行时,在默认情况下CPU是随机切换线程的,当我们需要对各线程来共同完成一件任务,并且我们希望他们有规律的执行,那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。
如何保证线程间通信有效利用资源:
多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。就是多个线程在操作同一份数据时,避免对同一共享变量的争夺。也就是我们需要通过一定的手段使多个线程能有效的利用资源。这种手段就是等待唤醒机制。
线程的等待唤醒
线程的等待方式:1使用sleep方法,在毫秒值结束之后,线程睡醒进入Runnable/Blocked状态;2,使用wait方法,wait方法如果在毫秒值结束之后,还没有被notify唤醒,就会自动醒来,线程睡醒进入到Runnable/Blocked状态
线程的唤醒方式:notify()唤醒在此对象监视器上等待的单个线程和notifyAll()唤醒在此对象监视器上等待的所有进程。
线程池,Lambda表达式
线程池:一个容纳多个线程的肉哦能勾起,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多的资源
合理利用线程池有三个好处
1、降低资源消耗。2、提高响应速度。3、提高线程的可管理性。
函数式编程
面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做。
JDK1.8中加入了Lambda表达式
Lambda表达式由三部分组成:一些参数,一个箭头,一段代码,(参数列表)->{一些重写方法的代码}
Lambda的使用前提
1、使用Lambda必须具有接口,且要求接口中有且仅有一个抽象的方法。2、使用Lambda必须具有上下文推断。
有且仅有一个抽象方法的接口,称为函数式接口