接口
接口(interface)是Java中的一种引用类型,是方法的集合,内部封装了方法
接口会被编译成class文件,但接口不是类,没有构造方法
接口不能创建对象,但可以被实现,一个实现接口的类需要实现接口中所有的抽象方法,创建该类对象,调用方法,否则为抽象类
接口的实现
类和接口是实现关系,即类实现接口,该类可以称为接口的实现类,类似继承,使用implements关键字
非抽象子类实现接口:
- 必须重写接口中所有的抽象方法
- 继承了接口的默认方法,即可以直接调用,也可以重写
接口支持多继承,接口中的元素都是public修饰的,接口中的抽象方法 public abstract 可以省略,接口中常量的public static final 可以省略
访问控制权限
final关键字
final:不可改变,用于修饰类,方法,变量
被修饰的类不能被继承
被修饰的方法不能被重写
被修饰的变量不能被重新赋值
内部类
一个类A定义在一个类B里面,里面的类A称为内部类,B则称为外部类
成员内部类
定义在类中方法外的类
访问特点
内部类可以直接访问外部类的成员,包括私有成员
外部类要访问内部类的成员,必须建立内部类对象
内部类是一个独立的类,编译后会生成独立的class文件
匿名内部类
本质是带具体实现的,父类或者接口的,匿名的子类对象
匿名内部类必须继承一个父类或者实现一个父接口
异常
程序执行过程中出现的非正常情况,最终导致JVM非正常停止
Java中异常本事是一个类,产生异常就是创建异常对象并抛出一个异常对象,Java处理异常的方式是中断处理
Throwable
- Error:严重错误Error,无法通过处理的错误,只能实现避免
- Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行
Exception
- 编译期异常:checked异常,在编译时期就会检查,如果没有处理异常则编译失败
- 运行期异常:runtime异常,在运行期检查异常,在编译时期不会报错
异常的处理
-
抛出异常throw:
Java中提供了一个throw关键字用来抛出一个指定的异常 -
声明异常throws:
关键字throws适用于方法声明之上,用于表示当前方法不处理异常,而是提醒调用者来处理异常 -
捕获异常try…catch:
Java中对异常有针对性的语句进行捕获,可以对异常进行指定方式处理
finally代码块:有一些特定代码,无论异常是否发生都要运行
因为异常会引发程序跳转,有些代码块执行不到,而finally修饰的代码一定会执行
异常注意事项
多个异常分别处理
多个异常一次捕获,多次处理
多个异常一次捕获,一次处理
运行时异常被抛出可以不处理,即不捕获也不声明抛出
如果finally有return语句,永远返回finally中的结果,避免该情况
如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常
父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
多线程
并发与并行
- 并发:指两个或多个事件在同一时间段内发生
- 并行:指两个或多个事件在同一时刻发生(同时发生)
线程与进程
- 进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程
- 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程
线程调度
- 分时调度:
所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。 - 抢占式调度:
优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为 - 抢占式调度:
设置线程的优先级
Java中创建线程:继承Thread类,实现Runnable接口
实现Runnable接口比继承Thread类所具有的优势:
- 适合多个相同的程序代码的线程去共享同一个资源
- 可以避免java中的单继承的局限性
- 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立
- 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类
扩充:在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用
java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进
程
线程安全
如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样
的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
线程同步:
当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题
要解决多线程并发访问一个资源的安全性问题: Java中提供了同步机制(synchronized)来解决
-
同步代码块:synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。
对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁.
- 锁对象 可以是任意类型。
- 多个线程对象 要使用同一把锁。
注意:在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着
-
同步方法:使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着。
同步锁是谁?
对于非static方法,同步锁就是this。
对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。 -
Lock锁:java.util.concurrent.locks.Lock 机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作,同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。
Lock锁也称同步锁,加锁与释放锁方法化了,如下:
public void lock() :加同步锁。
public void unlock() :释放同步锁。
线程状态
NEW(新建) 线程刚被创建,但是并未启动。还没调用start方法。
Runnable(可运行) 线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器。
Blocked(锁阻塞) 当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。
Waiting(无限等待) 一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入Waiting状态。进入这个状态后是不能自动唤醒的,必须等待另一个线程调用notify或者notifyAll方法才能够唤醒。
TimedWaiting(计时等待) 同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。这一状态
将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep 、Object.wait。
Teminated(被终止) 因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。